A lot of PowerShell functions/Cmdlets are written in a way that they can only be run on a localhost. But, sometimes you need to run them remotely.
PSSession will let you run a command on a remote host (One Hop). If you need to connect to more hosts than that, you’ll to need setup CredSSP in your environment.
One Hop Scripts
This function is a template for running a local command on a remote host:
Function Verb-Noun { [CmdletBinding()] [OutputType(If you can set this, that's awesome)] Param ( [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ParameterSetName = "A")] [PSObject] $A [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ParameterSetName = "A")] [string] $AZ, [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, ParameterSetName = "B")] [string] $B, [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] [string] $ServerName = $env:COMPUTERNAME, [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] [System.Management.Automation.Runspaces.PSSession] $Session = $null ) $scriptBlock = { Import-Module WebAdministration Import-Module ABC if($args) { Merge-AllParams -Arguments $args[0]; } ... code goes here ... return $XYZ } # handle calling with sessions $sessInfo = Test-CreateNewSession -Session $Session -ServerName $ServerName $Session = $sessInfo.Session try { if($session -and -not (Test-IsLocalSession $session)) { # copy all variables to pass across with Invoke-Command $allParams = Get-AllParams -Command $MyInvocation.MyCommand -Local (Get-Variable -Scope Local) # if a session is avaliable, run it in the session; unless its the local sysem $XYZ = Invoke-Command -Session $Session -ArgumentList $allParams -ScriptBlock $scriptblock; } else { # if it's a local session or if no session is avaliable, then run the script block inline $XYZ = (. $scriptblock); } } finally { if($sessInfo.CreatedSession) { Remove-PSSession $Session } } return $XYZ }
The function relies on Get-AllParams, Merge-AllParams, and Test-CreateNewSession.
<# .SYNOPSIS Will retrieve all arguments passed into a function. This can help ease passing those values to an Invoke-Command cmdlet. .EXAMPLE Get-AllParams -Command $MyInvocation.MyCommand -Locals (Get-Variable -Scope Local); #> Function Get-AllParams { [CmdletBinding()] Param( [Parameter(Mandatory = $true)] [System.Management.Automation.FunctionInfo]$Command, [Parameter(Mandatory = $true)] [Array]$Locals ) $allParams = @{}; $Command.Parameters.Keys| foreach { $i = $_; $allParams[$i] = ($Locals |? { $_.Name -eq $i; }).Value; } return $allParams; } <# .SYNOPSIS Will load all parameters passed in into the Script scope. This can be used in conjuction with Get-AllParams to pass variables into an Invoke-Command block. .EXAMPLE Merge-AllParams -Arguments $args[0]; #> Function Merge-AllParams { [CmdletBinding()] Param ( [Hashtable]$Arguments ) $Arguments.GetEnumerator() |% { Set-Variable -Name $_.key -Value $_.value -Scope Global; } } <# .SYNOPSIS Sets up a Session object if needed. It also returns a flag if a session object was created. .DESCRIPTION Sets up a Session object if needed. It also returns a flag if a session object was created. When functions sometimes need to run remotely (through a Session) or sometime locally, the code can be written to use a script block and logic can be added to call the code with a Session. The logic can become redundant when determing if and how to call the Session. This helper function helps with the process. .PARAMETER Session The current Session variable passed into the calling function .PARAMETER ServerName The current ServerName variable available in the calling function .EXAMPLE $sessInfo = Test-CreateNewSession -Session $Session -ServerName $ServerName $Session = $sessInfo.Session try { ... determine if the session needs to be called or a local execution should be used ... } finally { if($sessInfo.CreatedSession) { Remove-PSSession $sessInfo.Session } } #> Function Test-CreateNewSession { [CmdletBinding()] Param ( [System.Management.Automation.Runspaces.PSSession] $Session = $null, [string] $ServerName = "" ) $createdSession = $false if($Session -eq $null -and $ServerName -ne "") { if(-not (Test-IsLocalComputerName $ServerName)) { $Session = New-PSSession $ServerName $createdSession = $true } } $sessInfo = New-PsType "CoreUcsb.PSSessionCreate" @{ Session = $Session CreatedSession = $createdSession } return $sessInfo }
0 comments:
Post a Comment