PowerShell script monitor running in polling job on x86 / x64 platform

Version 5

    Sometimes confusion occurs regarding bitness of PowerShell sessions, which are started from the Windows PowerShell Monitor (WPsM).

     

    So how does it work?

    SAM WPsM executes in such a way that opens new PowerShell runspace inside the Orion Job Engine Worker Process (JEP).

     

    It has such consequences for "Local Host" or Agent execution mode:

    • the PowerShell runspace has the same .NET runtime version as the JEP - regardless of which PowerShell version is installed.
    • execution of script has no need start a new process, so it starts faster and footprint of script execution on a system is as small as possible
    • the PowerShell runspace follows the bitness of JEP. It has to follow this otherwise it could not simply pass objects between .NET assemblies code and PowerShell scripts
    • memory-leaks in PowerShell script or cmdlet affect the whole JEP

     

    The above is not true when the execution mode of WPsM is set to "Remote Host" and in the same time application runs in the agent-less mode.

    In such a situation the remote session follows the bitness (x86 vs. x64) of the remote Windows system.

     

    There is attached an application template, which demonstrates the principles described above.

    It tests the size of .NET pointer (4 vs. 8 bytes) and thus it detects the bitness of the environment.

     

    It also shows a trick; how to change behavior which was described.

     

    You can use these tricks when you need run WPsM in the opposite bitness mode to all the other components in the template.

    The trick is to start the script in a new process. You can choose which PowerShell executable (x86 vs. x64) is used to run the script.

     

    The following script opens new PowerShell 32bit session and runs code inside of it:

    #this PID will match Job Engine Process PID
    write-host "Statistic.WorkerProcessPID : $pid"
    Set-Alias ps32 "$env:windir\syswow64\WindowsPowerShell\v1.0\powershell.exe" 
    ps32 {
    
    # this PID is brand new one - it confirms that code runs in conext of new process
         write-host "Statistic.InnerPowerShellPID : $pid"
         
         $test1 = ([IntPtr]::size -eq 8)
         write-host "Message.Is64BitProcess : Is 64bit Process? $(({Yes}, {No})[!$test1])"  
         write-host "Statistic.Is64BitProcess : $([int]$test1)"
    
         $test2 = ([IntPtr]::size -eq 4)
         write-host "Message.Is32BitProcess : Is 32bit Process? $(({Yes}, {No})[!$test2])"   
         write-host "Statistic.Is32BitProcess : $([int]$test2)"
    }
    

     

    To force 64bit PowerShell session we use very similar approach. But we need to use different call for PowerShell.exe - and it depends on the current running environment.

    If it runs on 32bit we have to look for EXE in different directory then when it runs on 64bit:

     

    write-host "Statistic.WorkerProcessPID : $pid"
    
    if ([IntPtr]::size -eq 4){
         Set-Alias ps64 "$env:windir\SysNative\WindowsPowerShell\v1.0\powershell.exe"
    }else{
         Set-Alias ps64 "$env:windir\System32\WindowsPowerShell\v1.0\powershell.exe"
    }
    
    ps64 {
         write-host "Statistic.InnerPowerShellPID : $pid"
         
         $test1 = ([IntPtr]::size -eq 8)
         write-host "Message.Is64BitProcess : Is 64bit Process? $(({Yes}, {No})[!$test1])"  
         write-host "Statistic.Is64BitProcess : $([int]$test1)"
    
         $test2 = ([IntPtr]::size -eq 4)
         write-host "Message.Is32BitProcess : Is 32bit Process? $(({Yes}, {No})[!$test2])"   
         write-host "Statistic.Is32BitProcess : $([int]$test2)"
    }
    

     

     

    The environment inside the new process is closer to running the same script from command line.

    So it could be used to overcome such problems like when the script inside WPsM behaves differently to run from command line.

     

    You can try switching execution platform and check resulting bitness of each approach:

    2016-10-2011_55_48PowerShellScriptingExperiments.png

    2016-10-20 12_00_57-Edit Application - PowerShell Scripting Experiments.png

     

    You can do your own experiments - switching bitness and Local/Remote host and Agent/Agentless mode, to get a better understanding, what results every approach gives.

     

    Hope it helps.

    Tomáš