Unable to pass local parameter to ps-session using scriptBlock and start-process

I have been working on getting this to work for a least a week. Searched and tried numerous suggestions…nothing is working…

My goal is to start a remote wusa process to install a windows patch. This computer doesn’t have Internet access…nor can it. I don’t need a full blown WSUS installation. I only have 5 computers to patch. Though I do welcome feedback and suggestions.

Here is the code I am trying to get working:

#########################################################
# Name: winUpdateUtil.ps1
# Author: Curtis Roze
# Version: 1.0
# Date: 07/22/2020
# Description: PowerShell script to install 
# Windows Update files (.msu)
#########################################################
# USAGE:
# .\winUpdateUtil -PatchDir patch_202007 -Target [computer]
# .\winUpdateUtil -Target 
#
# =====================================================
# Parameters #

Param ( 
[string]$PatchDir = ".\",
[string]$Target = $env:computername
)

$msuKBList = @()
# Store log in default folder
$wusaLog = $PatchDir + "\$(Get-date -format 'yyyyMMdd.hh.mm')_update-Log.evtx"

$RootUpdatePath = 'C:\Support\WSUS'
$UpdateDir = $RootUpdatePath + "\" + $PatchDir
$wusaPath = '%windir%\system32'

# =====================================================
# Identify all *.msu update files for patching
$files = Get-ChildItem $UpdateDir
$msus = $files | ? {$_.extension -eq ".msu"}

foreach ($msu in $msus)
{
$msuKB = $msu.basename -match "-(?.*)-"
$msuKBList += $matches['content']
}
$msuKBList |Out-File -FilePath "${UpdateDir}\install_patch_list.kb"

## Validate and copy files ##
$Session = New-PSSession -ComputerName "$Target"

# Copy patches to target computer if they aren't already there
Write-Host ""
foreach ($msu in $msus)
{
$RemoteUpdatePath = "$UpdateDir\$msu"
if(!(Invoke-Command -Session $Session -ScriptBlock {Test-Path -Path $Using:RemoteUpdatePath} ))
{
Write-Host "Transfering patch ${msu} to $UpdateDir\ on computer: $Target..."
Write-Host ""

Copy-Item "$UpdateDir\$msu" -Destination "$UpdateDir\$msu" -ToSession $Session -Verbose -Force
}
}

Write-Host " Patches have been copied...DONE " -ForegroundColor red -BackgroundColor white
Write-Host ""

#*=============================================== 
#* INSTALLATION 
$installPhase = "Installation" 
#*===============================================

foreach ($msu in $msus)
{
write-host "Installing update $msu on computer: $Target ..."
Write-Host ""
$fullname = $msu.fullname

# Need to wrap in quotes as folder path may contain spaces
$fullname = "`"" + $fullname + "`""

# Specify the command line parameters for wusa.exe
$wusaParameters = " /quiet /norestart /log:`"$wusaLog`" "

#$installParam = "`" " + $fullname + $wusaParameters + "`""
$installParam = [string]::Concat($fullname,$wusaParameters)
$installParam = '"' + $installParam + '"'

Write-host $installParam

#$installProc = {Start-Process "wusa" "$installParam"}
#[scriptblock]$installProc = {Param($Param1)Start-Process "wusa" "$Param1"}

##== Start remote wusa.exe and pass in the parameters ==##
#Invoke-Command -Session $Session -ScriptBlock {$installProc.Invoke($args)} -ArgumentList $installParam
#Invoke-Command -Session $Session -ScriptBlock { [System.Diagnostics.Process]::Start($installProc) }
#Invoke-Command -ComputerName $Target -ScriptBlock { start-process "wusa" $($args[0]) } -ArgumentList $installParam
#Invoke-Command -Session $Session -ScriptBlock { %windir%\system32\wusa $installParam }
#Invoke-Command -Session $Session -ScriptBlock { $install.WaitForExit() }

Invoke-Command -Session $Session -ScriptBlock { param($p) Start-process "wusa" $p } -ArgumentList $installParam

exit

# TEST:
Invoke-Command -Session $Session -ScriptBlock {$env:computername} 

Write-Host ""
#Write-Host "wusaParameters:: $fullname + $wusaParameters "
#Write-Host $install
write-host "Finished installing $msu"
Write-Host ""
}

Remove-PSSession -Session $Session
exit

And some debug from the ISE:

DEBUG: 59+ >>>> Write-Host " Patches have been copied...DONE " -ForegroundColor red -BackgroundColor white

Patches have been copied...DONE
DEBUG: 60+ >>>> Write-Host ""

DEBUG: 64+ >>>> $installPhase = "Installation"

DEBUG: ! SET $installPhase = 'Installation'.
DEBUG: 67+ foreach ($msu in >>>> $msus)

DEBUG: ! SET $foreach = 'IEnumerator'.
DEBUG: 67+ foreach ( >>>> $msu in $msus)

DEBUG: ! SET $msu = '1windows10.0-kb4565912-x64_19eae0b34464284e4a96f9209e4ed7...'.
DEBUG: 69+ >>>> write-host "Installing update $msu on computer: $Target ..."

Installing update 1windows10.0-kb4565912-x64_19eae0b34464284e4a96f9209e4ed7cd146d5a1e.msu on computer: topsfcn01 ...
DEBUG: 70+ >>>> Write-Host ""

DEBUG: 71+ >>>> $fullname = $msu.fullname

DEBUG: ! SET $fullname = 'C:\Support\WSUS\patch_202007\1windows10.0-kb4565912-...'.
DEBUG: 74+ >>>> $fullname = "`"" + $fullname + "`""

DEBUG: ! SET $fullname = '"C:\Support\WSUS\patch_202007\1windows10.0-kb4565912...'.
DEBUG: 77+ >>>> $wusaParameters = " /quiet /norestart /log:`"$wusaLog`" "

DEBUG: ! SET $wusaParameters = ' /quiet /norestart /log:"patch_202007\20201005...'.
DEBUG: 80+ >>>> $installParam = [string]::Concat($fullname,$wusaParameters)

DEBUG: ! SET $installParam = '"C:\Support\WSUS\patch_202007\1windows10.0-kb456...'.
DEBUG: 81+ >>>> $installParam = '"' + $installParam + '"'

DEBUG: ! SET $installParam = '""C:\Support\WSUS\patch_202007\1windows10.0-kb45...'.
DEBUG: 84+ >>>> Write-host $installParam

""C:\Support\WSUS\patch_202007\1windows10.0-kb4565912-x64_19eae0b34464284e4a96f9209e4ed7cd146d5a1e.msu" /quiet /norestart /log:"patch_202007\20201005.08.41_update-Log.evtx" "
DEBUG: 100+ >>>> Invoke-Command -Session $Session -ScriptBlock { param($p) Start-process "wusa" $p } -ArgumentList $installParam

DEBUG: 104+ >>>> exit

Hit Line breakpoint on 'C:\Support\WSUS\winUpdateUtil.ps1:104'
[DBG]: PS C:\Support\WSUS>>

I really thought the most recent iteration (above) would work. I seems to follow Microsoft’s documentation about remote execution…but doesn’t. The “wusa” process starts on the remote computer. but it is clear the parameter doesn’t get set and passed.

Any help or insight to find out how I can get this working is appreciated.

~~ Curtis

looks like the code is not properly formatted. Can you create a gist (gist.github.com) and share the link here ?

Ok. Here is the gist.