Reputation: 74
I am writing a module to run logparser queries. I wrote a function that checks if LogParser is in the system root so that I can run logparser as a command in subsequent functions.
My code:
function Add-LogParser
{
if(Test-Path "C:\Windows\System32\LogParser.exe")
{
Write-Host -ForegroundColor Cyan "Log Parser is in System Root"
}
else
{
Copy-Item "C:\Program Files (x86)\WindowsPowerShell\Modules\Dealogic.LogAnalysis\LogParser.exe" -Destination "C:\Windows\System32\" -Force
if(Test-Path "C:\Windows\System32\LogParser.exe")
{
Write-Host -ForegroundColor Cyan "Log Parser has been added to System Root"
}
else
{
Write-Host -ForegroundColor Red "Unable to add Log Parser to System Root. This is a requirement of the Dealogic Log Analysis Module. Please verify you have write to copy to the C:\Windows\System32\ folder."
break
}
}
}
I ran the function and the first time it added it to root fine. I ran the function again because it has logic to check that it is in the root and that worked fine. Then I deleted LogParser expecting the third time it will see it is on there and add it back to root, but instead, it thinks LogParser is still there. And even if I start new Powershell sessions and just tab over to the path it thinks its there.
Even outside of my code this command is not working properly:
Test-Path -LiteralPath C:\Windows\System32\LogParser.exe
Is this because it is in the system root? Is that cached in the Powershell profile or something? Since adding it to root is a one time thing I don't know that it affects my script, but I was surprised to see this behavior.
Upvotes: 0
Views: 1612
Reputation: 974
This seems to be a common pitfall when developing in a situation where the developer can accidentally or unwittingly switch between 32 bit and 64 bit Powershell environments.
I conducted the following tests:
Test: Create file in system32 only and check system32 and syswow64 from both 32 and 64 bit PowerShell. Result: 32 bit session returned FALSE for both. 64 bit session returned TRUE for system32 and FALSE for syswow64.
Test: Create the file in syswow64 only and check both paths from both sessions. Result: 32 bit session returned TRUE for both. 64 bit session returned FALSE for system32 and TRUE for syswow64.
Test: Create file in both locations and check both paths from both sessions. Result: Both sessions returned TRUE for both paths.
Test: Create file in both locations and delete from system32 only. Result: 32 bit session returns TRUE for both. 64 bit session returns true for syswow64 only.
Test: Create file in both locations and delete from syswow64 only. Result: 32 bit session returned FALSE for both. 64 bit session returned TRUE for system32 only.
From this testing it appears that the 64 bit version is capable of accurately checking for files in both system32 and syswow64. The 32 bit application appears to be defaulting to using wow64. If the file is there it will return true regardless of what is in system32, and if the file is not there it will return false regardless of what is in system32.
Thanks to @Mathias R. Jessen for asking if the file exists in the syswow64 directory, as that reminded me that I've seen this before.
It looks like this all relates to redirection and reflection of keys under wow64. For more info search msdn Microsoft documentation for "Registry Keys affected by WOW64". This article https://support.microsoft.com/en-us/help/305097/how-to-view-the-system-registry-by-using-64-bit-versions-of-windows
contains some related info and includes this interesting line: "To support the co-existence of 32-bit and 64-bit COM registration and program states, WOW64 presents 32-bit programs with an alternate view of the registry."
Upvotes: 2