PsHelper.psm1
Import-Module $PSScriptRoot\Logger.psm1 function Remove-StaleSession { param ( [psobject] $staleSession ) try { $staleSessions | Remove-PSSession -ErrorAction SilentlyContinue } catch {} } function Get-ReliablePsSession { param ( [string] $computerName = @(hostname) ) $s = Get-PSSession -ComputerName $computerName -ErrorAction SilentlyContinue | Where-Object { $_.State -eq "Opened" } | Select -Last 1 if ($s -eq $null) { return $null } try { Invoke-Command -Session $s -ScriptBlock { Get-Date | Out-Null } -ErrorAction Stop | Out-Null return $s } catch { Remove-StaleSession -staleSession $s } return $null } function New-ReliablePsSession { param ( [string] $computerName = $(hostname), [pscredential] $credential = [pscredential]::Empty, [int] $retryCount = 5 ) $retry = 0 if ($retryCount -lt 0) { $retryCount = 1 } while ($true) { try { Write-TraceLog "New-ReliablePsSession: Creating new session to computer $computerName, retryCount $retry" $s = New-PSSession -ComputerName $computerName -Credential $credential -ErrorAction Stop Invoke-Command -Session $s -ScriptBlock { } -ErrorAction Stop | Out-Null Write-TraceLog "New-ReliablePsSession: session created to $computerName" return $s } catch { $retry++ if ($retry -ge $retryCount) { Write-TraceLog "New-ReliablePsSession: Failed to create pssession to $computerName, error $_" throw } Start-Sleep 5 } } } function Invoke-ReliableCommand { param ( [string] $computerName = $(hostname), [pscredential] $credential = [pscredential]::Empty, [scriptblock] $scriptblock, [array] $argumentList ) $curHost = $($env:ComputerName).ToUpper() if ($computerName.ToUpper().StartsWith($curHost)) { return Invoke-Command $scriptblock -ArgumentList $argumentList } $staleSessions = Get-PSSession -ComputerName $computerName -ErrorAction SilentlyContinue | Where-Object { $_.State -ne "Opened" } if ($null -ne $staleSessions) { Remove-StaleSession -staleSession $staleSessions } $s = Get-ReliablePsSession -ComputerName $computerName if ($null -eq $s) { $s = New-ReliablePsSession -ComputerName $computerName -Credential $credential } return Invoke-Command -Session $s -ScriptBlock $scriptblock -ArgumentList $argumentList } function Invoke-PowershellCommand { param( [string][Parameter(Mandatory = $true)]$cmd ) $bytes = [Text.Encoding]::Unicode.GetBytes($cmd) $encodedCommand = [Convert]::ToBase64String($bytes) $result = powershell.exe -noprofile -encodedCommand $encodedCommand return $result } function Invoke-PowershellCommandOnVmInternal { param( [string] $vmName, [string] $hostName, [string] $cmd, [pscredential] $hostCredentials = [pscredential]::Empty, [pscredential] $vmCredentials = [pscredential]::Empty ) # Write-FunctionEntryWithParams -FunctionName $MyInvocation.MyCommand.Name -boundparameters $psboundparameters -UnboundArguments $MyINvocation.UnboundArguments -ParamSet $psCmdlet Write-TraceLog "psOnVm: vm:$vmName host:$hostName command:{$cmd}" Invoke-Command -ComputerName $hostName -Credential $hostCredentials -ScriptBlock { $sb = [scriptblock]::Create($using:cmd) Invoke-Command -ScriptBlock $sb -VMName $using:vmName -Credential $using:vmCredentials } } |