# Because SCCM's built in detection method for checking powershell.exe's version number just doesn't work. # This script file is just a backup copy for the code that's stored in the app package's detection method. # It can also be run directly, and if called by a TS, will pass TS variables back to the TS if -CalledFromTS is specified. # https://david-obrien.net/2013/12/configmgr-powershell-application-detection-methods/ # https://docs.microsoft.com/en-us/previous-versions/system-center/system-center-2012-r2/gg682159(v%3dtechnet.10)?ranMID=43674&ranEAID=je6NUbpObpQ&ranSiteID=je6NUbpObpQ-R6D01_EdS2oeCG4mS3F8nw&epi=je6NUbpObpQ-R6D01_EdS2oeCG4mS3F8nw&irgwc=1&OCID=AID681541_aff_7795_1243925&tduid=(ir__agti36kioskfrizr0c1gdjgco32xhodi2hz9uihf00)(7795)(1243925)(je6NUbpObpQ-R6D01_EdS2oeCG4mS3F8nw)()&irclickid=_agti36kioskfrizr0c1gdjgco32xhodi2hz9uihf00#to-use-a-custom-script-to-determine-the-presence-of-a-deployment-type # # Parameters param( # If specified, will run read and set TS variables [switch]$CalledFromTS ) # https://stackoverflow.com/questions/24992681/powershell-check-if-a-file-is-locked function Test-FileLock { param ( [parameter(Mandatory=$true)][string]$Path ) $oFile = New-Object System.IO.FileInfo $Path if ((Test-Path -Path $Path) -eq $false) { return $false } try { $oStream = $oFile.Open([System.IO.FileMode]::Open, [System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::None) if ($oStream) { $oStream.Close() } $false } catch { # file is locked by a process. return $true } } # https://stackoverflow.com/questions/5648931/test-if-registry-value-exists function Test-RegistryValue { param( [Alias("PSPath")] [Parameter(Position = 0, Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [String]$Path , [Parameter(Position = 1, Mandatory = $true)] [String]$Name , [Switch]$PassThru ) process { if (Test-Path $Path) { $Key = Get-Item -LiteralPath $Path if ($Key.GetValue($Name, $null) -ne $null) { if ($PassThru) { Get-ItemProperty $Path $Name } else { $true } } else { $false } } else { $false } } } $logDir = "c:\engrit\logs" $logFile = $logDir + "\powershell-detection-method.log" if(!(test-path -path $logDir)) { New-Item -ItemType "directory" -Path $logDir } echo "Creating logfile..." | Out-File $logFile function log($string) { echo $string | Out-File $logFile -Append } $major = $psversiontable.psversion.major $minor = $psversiontable.psversion.minor $build = $psversiontable.psversion.build $revision = $psversiontable.psversion.revision $full = "$major.$minor.$build.$revision" log("PowerShell version: $full") $exitCode = -1 $result = '$result not set' if($major -ge "5") { # Major version is at least 5 log("Major version is at least 5.") if($major -eq "5") { # Major version is exactly 5 log("Major version is exactly 5.") # Check for minor version if($minor -ge "1") { # Minor version is at least 1 log("Minor version is at least 1.") # Report success $result = "Success 1" $exitCode = 0 } else { # Minor version is less than 1 log("Minor version is less than 1.") # Do not report success $result = "Fail 1" $exitCode = 1 } } else { # Major version is greater than 5 log("Major version is greater than 5.") # Report success $result = "Success 2" $exitCode = 0 } } else { # Not installed log("Major version is less than 5.") # Do not report success $result = "Fail 2" $exitCode = 2 } log("Completed version checking logic.") $succeeded = "False" $slackMsgStart = '$slackMsgStart not set' if($exitCode -eq 0) { $succeeded = "True" Write-Host $resultMsg $slackMsgStart = ":heavy_check_mark: WMF/PowerShell 5.1 succeeded!" } else { # Don't output anything if failed. See links above. #Write-Host $resultMsg $slackMsgStart = ":no_entry_sign: WMF/PowerShell 5.1 failed to install!" } log("succeeded = $succeeded") log("slackMsg = $slackMsg") # To double check, read registry variable that should only exist if installation was successful $regPath = "HKLM:\SOFTWARE\Microsoft\PowerShell\3\PowerShellEngine" $regValue = "PowerShellVersion" $regExists = Test-RegistryValue -Path $regPath -Name $regValue $regData = "unknown" if($regExists) { if($regLocked) { $regData = "locked" } else { $regData = (Get-ItemProperty -Path $regPath -name $regValue | select-object $regValue).$regValue } } else { $regData = "doesn't exist" } log("regData = $regData") # To triple check, read file version of powershell.exe $exePath = "c:\windows\system32\windowspowershell\v1.0\powershell.exe" $exeCopyPath = "c:\engrit\logs\powershell.exe" $exeExists = Test-Path -Path $exePath $exeLocked = Test-FileLock -Path $exePath $exeVersion = "unknown" if($exeExists) { copy-item $exePath -destination $exeCopyPath if($exeLocked) { $exeVersion = "locked" } else { $exeVersion = (Get-ItemProperty -Path $exePath).versioninfo.fileversion } } else { $exeVersion = "doesn't exist" } log("exeVerstion = $exeVersion") $exeCopyExists = Test-Path -Path $exeCopyPath $exeCopyLocked = Test-FileLock -Path $exeCopyPath $exeCopyVersion = "unknown" if($exeCopyExists) { if($exeCopyLocked) { $exeCopyVersion = "locked" } else { $exeCopyVersion = (Get-ItemProperty -Path $exeCopyPath).versioninfo.fileversion remove-item $exeCopyPath } } else { $exeCopyVersion = "doesn't exist" } log("exeCopyVerstion = $exeCopyVersion") if(!$CalledFromTS) { $detected = "not run from TS" } else { # Access to TS variables $tsenv = New-Object -COMObject Microsoft.SMS.TSEnvironment $detected = $tsenv.Value('EngrIT_WMFDetected') } $logMsg = "$slackMsgStart Result: $result, Succeeded: $succeeded, Exit code: $exitCode, Version (ps): $full, Version (reg): $regData, Version (exe): $exeVersion, Version (exe copy): $exeCopyVersion, Detected by detection method: $detected" log($logMsg) if($CalledFromTS) { $tsenv.Value('EngrIT_PowershellSucceeded') = $succeeded $tsenv.Value('EngrIT_PowershellDetectionMsg') = $logMsg } Exit $exitCode