I've inherited a deployment script that reads through files with specific names and extensions deployed to our on-prem web servers, looks line-by-line in those text files for string matches that signify they need replacing, and then inserts, in this case, the correct database and catalog names for the specific server being deployed to.
Unfortunately, though the script works fine On My Computer (c)1984, it's not working when run by TFS as part of the deploy process.
I've added an embarrassing amount of debug info, but haven't been able to track down the issue.
Code
Here's the pertinent code:1
$getFilesParams = @{
Path = $SearchDirectory
Include = @(
"*.asa", "*.asp",
"*.aspx", "*.config",
"*.inc", "*.ini",
"appsettings.json"
)
Exclude = "Web.*.config"
Recurse = $True
}
$files = @(Get-ChildItem @getFilesParams)
foreach ($f in $files) {
# DEBUG STARTS HERE
Write-Feedback "`tFile to search for Data Source: $f" -LogFile "$LogFile"
if ($f.Name -eq "appsettings.json") {
try {
Write-Feedback "`t`tFound the appsettings.json file: $($f.Length) $($f.LastWriteTime) $($f.Name)" -LogFile $LogFile
Get-Content $f | % {
Write-Feedback "!!!! Line: $_"
}
Select-String $f -Pattern "Data Source" | % { Write-Feedback "`t`t`tFound data source: $_" }
# was suspicious it'd work the first but not the second time. No, it fails each time I Get-Content.
Get-Content $f | % {
Write-Feedback "@@@@ Line: $_"
}
}
catch {
Write-Feedback "An error occurred with appsettings.json:" -LogFile $LogFile
Write-Feedback $_ -LogFile $LogFile
}
}
# DEBUG ENDS
}
$files = $files |
Select-String -Pattern "Data Source" |
Group-Object path |
Select-Object name
$count = $files.count
if ($count)
{
@"
Found $count files....
Processing:
"@ | Write-Feedback -LogFile $LogFile
# etc etc he fixes the cable
}
else
{
' Did not find any databases catalogs!' | Write-Feedback -LogFile $LogFile
}
Then we go line by line through the files in $files
. The problem is that my appsettings.json
file, which does contain Data Source
(okay, it's lowercase right now -- data source
), doesn't get captured and no replacements are made.
Note:
Write-Feedback
is a convenience function that writes to the console (Write-Host
) and to a file, if one is given.
Local output
When I run locally, I get what I'm expecting (edited a bit for brevity):
File to search for Data Source: C:\path\appsettings.json
Found the appsettings.json file: 993 01/12/2022 13:04:52 appsettings.json
!!!! Line: "SomeJsonKey": "data source=localhost;initial catalog=SomeDb;integrated security=True",
Found datasource: C:\path\appsettings.json:9: "SomeJsonKey": "data source=localhost;initial catalog=SomeDb;integrated security=True",
@@@@ Line: "SomeJsonKey": "data source=localhost;initial catalog=SomeDb;integrated security=True",
Found 1 files....
Processing:
C:\path\appsettings.json....
Production output
But when it's run as part of the deployment, I get...
File to search for Data Source: E:\path\appsettings.json
Found the appsettings.json file: 762 01/14/2022 15:15:02 appsettings.json
Did not find any databases catalogs!
So it sees appsettings.json
, it even knows appsettings.json has a length (they are different files, so the two lengths here aren't an issue), but it won't Get-Content
, much less find the line with Data Source
in it.
Notepad++ says the file is ANSI, which is fine, I think. There're no extended characters, so that's the same as UTF8, which is what I expected. Don't think that'd break Get-Content
.
To be clear, Not necessarily looking for an answer. Just wondering what my next debug(s) step would be.
I've looked up a little about permissions, though I'm not sure how I'd tell which entry from (Get-Acl $Outfile).Access
represents the process that's currently running. But I also would expect an exception of some kind if it can't read the file.
Just for fun, here's a picture of the release UI for the TFS server this is running on. If you've seen it before, you'll get it.
I was hoping I could figure this out through straight PowerShell, but I can check things out there to a degree if that's useful. That said, I don't have full perms on the TFS site. I probably have more running as... whoever I'm running as when the PowerShell (third step) is executed.
(sorry for all the redaction; almost certainly not necessary, but better safe than sorry (sorrier?), etc?)
1 I realize this code can be optimized. Please ignore that; it's, again, inherited, and I'm trying to get it to work with a minimum of churn.