Not all PowerShell shells are equals

I’ve been recently involved in fixing 2 issues for my colleagues.

  • The first issue
    • Context
    • 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.

    • Issue
    • 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.

    • Solution
    • 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
    • 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.

    • Issue
    • 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
    • Solution
    • 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.

1 thought on “Not all PowerShell shells are equals

  1. Pingback: Dew Drop - September 21, 2018 (#2808) - Morning Dew

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.