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