I’ve been recently involved in fixing 2 issues for my colleagues.
- The first issue
- Context
- Issue
- Solution
My colleagues send an message with a link that points to a script located on a shared drive to help our users reinstall their software.
Our users just click on the link in their Outlook and got a message saying:
\\servername.fqdn\share\softwarename\install.ps1 cannot be loaded because running scripts is disabled on this system. For more information, see about_Execution_Policies at https:/go.microsoft.com/fwlink/?LinkID=135170.
Users use Outlook that is a 32-bit process. If they click on link that points to a script, it will spawn a 32-bit console and run a 32-bit powershell.exe child process.
It appears that the ExecutionPolicy isn’t defined in the 32-bit PowerShell and set to its default value: “Restricted” although it’s defined in the 64-bit Powershell.
Needless to say that you cannot run a script with a restricted execution policy.
While there are many ways to solve this issue, we’ve decided to address the issue when computers are provisionned. The post-install of a workstation runs a 64-bit PowerShell script where we’ve just added:
C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe { Set-ExecutionPolicy -ExecutionPolicy 'RemoteSigned' -Force -Scope LocalMachine }
The above solution just writes the missing ExecutionPolicy value in this registry key:
- The second issue
- Context
- Issue
We’ve a short quick and dirty Pester test to perform some operational validation of our configuration. We’ve decided to add a quick test about the execution policy value for a 32-bit PowerShell. But other tests failed and that was unexpected because they don’t when they are executed in a 64-bit PowerShell console.
The error message thrown was:
CommandNotFoundException: The term ‘Get-LocalGroupMember’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct a
nd try again.
As you can see, there isn’t any Microsoft.PowerShell.LocalAccounts module in the 32-bit modules location. It means that you cannot use the Get-LocalGroupMember cmdlet in a 32-bit PowerShell console.
I started to compare the module names like this:
Compare-Object (dir $PSHOME\Modules -Directory).Name ` -DifferenceObject ( dir "$($PSHOME -replace "system32","syswow64")\Modules"` -Directory).Name
Yes, on my 1803, this is the list of 64-bit only modules:
AppBackgroundTask- AssignedAccess
- ConfigCI (or CIPolicy?)
- HgsClient
- Microsoft.PowerShell.LocalAccounts
- NetworkSwitchManager
- PcsvDevice
- PersistentMemory
- ProcessMitigations
- PSWorkflow
- PSWorkflowUtility
SmbShare- SmbWitness
- StartLayout
- WindowsSearch
- WindowsUpdateProvider
Well, it depends how far you want to go. I’ve chosen to execute only Pester tests in a 64-bit PowerShell console and do the following:
It 'WMF local machine 32-bit execution policy should be set to RemoteSigned' { ( Get-ItemProperty -Path 'HKLM:\SOFTWARE\WOW6432Node\Microsoft\PowerShell\1\ShellIds\Microsoft.PowerShell' ` -Name 'ExecutionPolicy' -ErrorAction SilentlyContinue ).'ExecutionPolicy' -eq 'RemoteSigned'| should be $true }
The above registry key exists only when it’s executed in a 64-bit shell.
Who executes Pester tests in a 32-bit shell when you run a 64-bit OS?
My above unit test doesn’t handle gracefully the 32-bit issue and will actually throw an error if it’s executed in a 32-bit shell.
Pingback: Dew Drop - September 21, 2018 (#2808) - Morning Dew