public/Enter-PSRemotely.ps1
Function Enter-PSRemotely { [CmdletBinding()] param ( # Specify this switch to get the PSSession object [Switch]$PassThru ) DynamicParam { # Add a dynamic parameter 'NodeName' which discovers the PSRemotely nodes by looking at # the $PSRemotely global variable if ($Global:PSRemotely) { # only add this dynamic parameter if the $PSRemotely global var exists #create a new ParameterAttribute Object $NodeNameAttribute = New-Object System.Management.Automation.ParameterAttribute $NodeNameAttribute.Position = 1 $NodeNameAttribute.Mandatory = $true $NodeNameAttribute.ParameterSetName = '__AllParameterSets' $NodeNameAttribute.HelpMessage = "Enter the remotely node name to connect to" #create an attributecollection object for the attribute we just created. $attributeCollection = new-object System.Collections.ObjectModel.Collection[System.Attribute] $AvailablePSRemotelyNodeNames = @($Global:PSRemotely.SessionHashTable.Keys) # add the PSRemotely node names to the attributecollection $attributeCollection.Add( (New-Object -TypeName System.Management.Automation.ValidateSetAttribute( $AvailablePSRemotelyNodeNames) ) ) #add our custom attribute $attributeCollection.Add($NodeNameAttribute) #add our paramater specifying the attribute collection $NodeNameParam = New-Object System.Management.Automation.RuntimeDefinedParameter('NodeName', [String], $attributeCollection) #expose the name of our parameter $NodeNameDic = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $NodeNameDic.Add('NodeName', $NodeNameParam) return $NodeNameDic } } Process { $SessionInfo = $Global:PSRemotely.SessionHashTable[$($PSBoundParameters.NodeName)] $Session = $Global:PSRemotely.SessionHashTable[$($PSBoundParameters.NodeName)].Session if ($Session){ if ($Session.State -ne 'Opened'){ # Re-connect to the node. Note the $Node variable populated earlier is now lost. CheckAndReconnect -SessionInfo $SessionInfo # since the session is re-connected, set the value back in the $session variable to use. $Session = $Global:PSRemotely.SessionHashTable[$($PSBoundParameters.NodeName)].Session # Reinitialize Session with the PSRemotely variable ReinitializeSession -SessionInfo $SessionInfo -ArgumentList @{PSRemotely=$PSRemotely} } $IsConfigurationDataUsed = Invoke-Command -Session $Session -ScriptBlock {return $Node} -ErrorAction SilentlyContinue if ($IsConfigurationDataUsed) { $PSRemotelyParameterSet= 'ConfigurationData' } else { $PSRemotelyParameterSet = 'NodeName' } Switch ($PSRemotelyParameterSet) { 'ConfigurationData' { $ScriptBlock = { param( [Parameter()] $Node=$Node, # point this by default to $Node populated in remote session [Parameter()] $Path, [Parameter()] $PSRemotely= $Global:PSRemotely ) try { if (-not $Path){ $Path = "$($Global:PSRemotely.PSRemotelyNodePath)\*.ps1" } Set-Location -Path $PSRemotely.PSRemotelyNodePath Invoke-Pester -Script @{Path=$Path;Parameters=@{Node=$Node}} } catch { Write-Warning -Message "[Warning] $($PSItem.Exception.Message)" } } } 'NodeName' { $ScriptBlock = { param() try { Invoke-Pester -Path "$($PSRemotely.PSRemotelyNodePath)\*.ps1" -ErrorAction Stop } catch { Write-Warning -Message "[Warning] $($PSItem.Exception.Message)" } } } } # Inject the Invoke-PSRemotely function, based on whether the environment config data was specified or not. Invoke-Command -Session $Session -ScriptBlock { $null = New-Item -Path Function:\ -Name Invoke-PSRemotely -Value $Using:ScriptBlock -Force $null = Set-Location -Path $PSRemotely.PSRemotelyNodePath -ErrorAction SilentlyContinue } if ($PassThru.IsPresent) { Write-Output -InputObject $Session } else { # Enter the PSSession interactively Enter-PSSession -Session $Session } } } } |