Share via

Function behaving weirdly

Dima Bell 1 Reputation point
2022-01-31T21:49:15.617+00:00

Hello everyone!
I'm new to powershell i have written a script that performs some actions in a domain environment.
One of the functions in the script is querying the registry of a remote computer to determine whether a given software is installed and it's version.
The weird behavior i'm experiencing is that when i execute the script from within powershell ISE the function behaves as expected and retrieves the information,
but if i execute the script with the powershell console the function is not able to retrieve the information successfully and eventually gives a false output.

I will be very grateful is any of you can have a look and maybe help me understand why this is happening and if there is a fix.
The link to the full script (Remote MSI installation v2.ps1): https://github.com/DimaBell/Powershell-scripts/blob/main/Remote%20MSI%20installation%20v2.ps1
The function is as below :

function Get-InstalledSoftwareAndVersion {
$UninstallKey = ”SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall”
$reg = [microsoft.win32.registrykey]::OpenRemoteBaseKey(‘LocalMachine’,$global:PC)
$regkey = $reg.OpenSubKey($UninstallKey)
$subkeys = $regkey.GetSubKeyNames()
foreach ($key in $subkeys) {
$thisKey = $UninstallKey+”\”+$key
$thisSubKey = $reg.OpenSubKey($thisKey)
$global:obj = New-Object PSObject
$global:obj | Add-Member -MemberType NoteProperty -Name “DisplayName” -Value $($thisSubKey.GetValue(“DisplayName”))
$global:obj | Add-Member -MemberType NoteProperty -Name “DisplayVersion” -Value $($thisSubKey.GetValue(“DisplayVersion”))
if (($global:obj).DisplayName -like "$global:Software") {
$global:SoftwareIsInstalled = "True"
$global:SoftwareInstalledVersion = $global:obj.DisplayVersion
break
} else {
$global:SoftwareIsInstalled = "False"
}
}
}

Windows for business | Windows Server | User experience | PowerShell
0 comments No comments

3 answers

Sort by: Most helpful
  1. Rich Matheisen 48,116 Reputation points
    2022-02-01T02:57:33.273+00:00

    If you're unsure about the bitness of the remote machine, or if the software you're looking for might be 32-bit and the remote machine's 64-bit, get the data from both registry keys.

    Here's an example if you were running on just a local machine and want to get a list of ALL the software:

    # get 64-bit software on 64-bit systems OR 32-bit software on 32-bit systems
    [array]$32_or_64bitsoftware = get-itemproperty 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'
    # get 32-bit software ON 64-bit systems
    [array]$32_on_64bitsoftware = get-itemproperty 'HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
    

    Was this answer helpful?

    0 comments No comments

  2. aj-47 66 Reputation points
    2022-02-01T01:30:31.257+00:00

    Looking at the full script on github repo, the following code snippet:

    foreach ($PC in $PCs.name) {
        $PCStatus = Test-Connection -ComputerName $PC -Count 1 -Quiet
        if ($PCStatus -eq "True") {
            Write-Output "$([datetime]::Now) $PC is online, checking the status of the remote registry service." | Tee-Object -Append $FullLogFilePath -ErrorAction Ignore
            Check-RemoteRegistry
            if ($global:RemoteRegStartType -eq "Automatic") {
                Write-Output "Checking if the software is already installed and what is the installed version."
                Get-InstalledSoftwareAndVersion
    .......
    

    calls get-InstalledSoftwareAndVersion as part of the foreach loop, the function definition attempts to open HKLM on the remote computer using the $global:PC variable

    $reg = [microsoft.win32.registrykey]::OpenRemoteBaseKey(‘LocalMachine’,$global:PC)

    What is the false output you're getting when executing this from PS console? I'm wondering if populating $reg through OpenRemoteBaseKey is working at all?
    I tried it in my environment and it doesn't return anything.

    Was this answer helpful?

    0 comments No comments

  3. Michael Taylor 61,226 Reputation points
    2022-01-31T22:16:04.097+00:00

    When seeing differing behavior in the registry I lean toward a bitness issue. The ISE (which you should probably move away from) is x86 and therefore your code is running against the x86 registry. However when you run PS directly if you're running x64 then you'll see the x64 view. While often the same there are differences, especially when writing. The best solution is to modify your call to OpenRemoteBaseKey to specify which view you want irrelevant of your process (e.g. 512 for x86 or 256 for x64).

    For PS development I would recommend you consider switching to Visual STudio Code instead of ISE. ISE is OK for simple scripts but VS Code is far more powerful. It supports all versions of PS, allows for breakpoints and stepping and everything that ISE does plus more and is just a better environment for building and debugging scripts. To use it with PS you'll need to install the Powershell Extension but otherwise it is pretty easy. I find that debugging scripts in VSC is much faster and easier than ISE ever was able to do.

    Was this answer helpful?

    0 comments No comments

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.