Flow control when invoking PowerShell with complex expressions using ScriptBlock


I am able to use PowerShell as described in the blog post:


It seems flow control statements (if-then-else, etc.) are ignored as there is no evidence that the are executed. The script blocks do do execute (all) the single line powershell expressions, but not flow control.

We are using PowerShell from an external program via the .Net Process class where we push a script block (see below) via standard input. The script creates a “inner script Block”, converts to a encoded base 64 and launches a new elevated PowerShell process. In both the inner and outer script blocks the flow control statements are ignored.

Can anybody suggest why?



Here is a simplified script:

### PowerShell Script Service Install
$innerScriptBlock = {
$scriptOutput = @{}
$outputFileName = "tempFileName.xml"
$serviceName = "SomeWindowsService"
$serviceDisplay = "Some Windows Service"
$serviceDescription = "Not some other service"
$servicePath = "c:\bin\someservice.exe"
$serviceAccount = "MachineName\DomainServiceAccount"
$serviceStartupType = "Manual"
$machineName = "MachineName"

$sspw = ConvertTo-SecureString "ignoreThisPassword" -asPlainText -Force

if ($serviceAccount -eq "LocalSystem")
     $serviceCredentials = new-object -typename System.Management.Automation.PSCredential -argumentlist "$machineName\LocalSystem",$sspw
     $serviceCredentials = Get-Credential -UserName $serviceAccount -Message "Enter Service Credentials"
     if ($? -eq $false )
          $outLog += "Get Creds failed`n"

$catchOutput = New-Service -Name $serviceName -BinaryPathName $servicePath -StartupType $serviceStartupType -Credential $serviceCredentials -DisplayName $serviceDisplay -Description $serviceDescription
if ($? -eq $false )
     $outLog += "Service failed`n"
     $outLog += "Service created:`n "
$scriptOutput["OutputLog"] = $outLog
$scriptOutput | ConvertTo-Xml -as string | Set-Content -Path $outputFileName
#### end inner script block

$bytes = [System.Text.Encoding]::Unicode.GetBytes($innerScriptBlock)
$innerBlockEncoded = [Convert]::ToBase64String($bytes)
$p = New-Object -TypeName System.Diagnostics.Process
$p.StartInfo.FileName = "PowerShell.exe"
$p.StartInfo.WorkingDirectory = "c:\MyWorkingDir"
$p.StartInfo.Verb = "runas"
$p.StartInfo.UseShellExecute = $true
##$p.StartInfo.WindowStyle = 1
$p.StartInfo.Arguments = "-EncodedCommand $innerBlockEncoded"
$ret_value = $p.Start()
$ret_value = $p.WaitForExit(120)

$t = 0
while (( $t -le 10000) -and (-not (Test-Path "tempFileName.xml")) )
    Start-Sleep -Milliseconds 100
    $t += 100

$script_out = Get-Content -Path "tempFileName.xml" -force
$script_out | Write-Output
Remove-Item -Path "tempFileName.xml" -force



second attempt to format code - edited the main post instead -


with a quick overlook I see some minor issues …

on line 16 you are actually comparing “MachineName\DomainServiceAccount” to “LocalSystem”. What result would you expect from this comaprison? :wink:

on the lines 23 and 30 you check if the last command has been completed successfully. As this commands are variable assignments they will likely always be successful. BTW: Because $? returns a boolean it looks better like this “if ( -not $?)