diff --git a/PSMultiPass/PSMultiPass.psd1 b/PSMultiPass/PSMultiPass.psd1 index d91c272..830b884 100644 --- a/PSMultiPass/PSMultiPass.psd1 +++ b/PSMultiPass/PSMultiPass.psd1 @@ -12,7 +12,7 @@ RootModule = 'PSMultiPass.psm1' # Version number of this module. -ModuleVersion = '0.0.4' +ModuleVersion = '0.0.5' # Supported PSEditions # CompatiblePSEditions = @() diff --git a/PSMultiPass/functions/public/Invoke-MultiSessionCommand.ps1 b/PSMultiPass/functions/public/Invoke-MultiSessionCommand.ps1 new file mode 100644 index 0000000..73f94b2 --- /dev/null +++ b/PSMultiPass/functions/public/Invoke-MultiSessionCommand.ps1 @@ -0,0 +1,98 @@ + +### Possibly change functionality to include just creating sessions using error checking on +### failed sessions and returning sessions as an output. + + +function Invoke-MultiSessionCommand { + [CmdletBinding()] + Param ( + [Parameter(Mandatory = $true)] + [string[]] + $ComputerName, + + [Parameter(Mandatory = $true)] + [pscredential] + $Credential, + + [Parameter(Mandatory = $true)] + [ScriptBlock]$ScriptBlock, + + [int] + $CommandThrottleLimit = 10, + + [System.Management.Automation.Remoting.PSSessionOption] + $SessionOption = $null, + + [string[]] + $SessionName, + + [int] + $SessionThrottleLimit = 32, + + [bool] + $CleanUpSessions = $true + ) + + Begin { + $sessionParameters = @{ + ComputerName = $ComputerName + Credential = $Credential + ThrottleLimit = $SessionThrottleLimit + ErrorVariable = 'sessionError' + ErrorAction = 'SilentlyContinue' + } + + if ($SessionOption) { $sessionParameters.Add('SessionOption', $SessionOption)} + if ($SessionName) { $sessionParameters.Add('Name', $SessionName)} + + Write-Verbose "Creating sessions for the following computer names: $($ComputerName -join ', ') with throttle limit of $SessionThrottleLimit..." + $sessions = New-PSSession @sessionParameters + + $connectionErrorInfo = $sessionError.TargetObject + + if ($sessionError) { + Write-Warning "One or more sessions were not created successfully. Please check the ConnectionErrorInfo property." + } + + $sessionCount = $sessions.Count + Write-Verbose "Successfully created $sessionCount sessions." + + } + + Process { + + if ($sessionCount -eq 0) { + Write-Warning "No sessions were created successfully. Skipping command invocation." + return + } + + Write-Verbose "Invoking command on $sessionCount sessions with throttle limit of $CommandThrottleLimit..." + + $commandParameters = @{ + Session = $sessions + ScriptBlock = $ScriptBlock + ThrottleLimit = $CommandThrottleLimit + ErrorVariable = 'commandError' + } + + $commandOutput = Invoke-Command @commandParameters + + } + + End { + + $output = [PSCustomObject]@{ + CommandOutput = $commandOutput + ConnectionErrorInfo = $connectionErrorInfo + } + + Write-Output $output + + if ($CleanUpSessions -and $sessionCount -gt 0) { + # Clean up all sessions + Write-Verbose "Cleaning up sessions..." + Remove-PSSession -Session $sessions -ErrorAction $ErrorActionPreference + } + + } +} \ No newline at end of file diff --git a/run.ps1 b/run.ps1 index 052a8c5..2f393d1 100644 --- a/run.ps1 +++ b/run.ps1 @@ -125,4 +125,13 @@ $testVariable2 = 'TestValue2' Invoke-ForEachParallelProxy -InputObject (1..5) -ScriptBlock { $currentItem = $_ Write-Host "Session: $currentItem, testVariable1 = $testVariable1, testVariable2 = $testVariable2" -} -ImportUserVariables \ No newline at end of file +} -ImportUserVariables + + + +$scriptBlock = { + Add-WindowsFeature Web-Server -Verbose -WhatIf +} + +$test = Invoke-MultiSessionCommand -ComputerName core01,core02,core03 -ScriptBlock $scriptBlock -Credential $cred -Verbose +