New-ISERemoteTab.ps1
#requires -version 4.0 #requires -module ISE Function New-ISERemoteTab { <# .SYNOPSIS Create remote tabs in the PowerShell ISE. .DESCRIPTION This command will create one or more remote tabs in the PowerShell ISE. You could use this to programmatically to open multiple remote tabs. The default behavior is to open tabs with your current credentials. But you can specify a single credential for all remote connections, or prompt for a credential for each connection. You might need this if some of the machines require different credentials. The command also supports additional parameters from Enter-PSSession. Be aware that if you specify multiple machines and one of these parameters, such as UseSSL, that parameter will apply to all remote connections. .PARAMETER Computername The name of the server to connect. This parameter has an alias of CN. .PARAMETER Credential A PSCredential or user name to be used for all specified computers. Note that if you specify a credential, it will temporarily be exported to disk so that each new PowerShell tab can re-use it. The file is deleted at the end of the command. This parameter has aliases of RunAs,Cred,and C. .PARAMETER PromptforCredential Use this parameter if you want to prompt for a credential for each connection. No credential information is written to disk. .PARAMETER Authentication Specifies the mechanism that is used to authenticate the user's credentials. Valid values are "Default", "Basic", "Credssp", "Digest", "Kerberos", "Negotiate", and "NegotiateWithImplicitCredential". The default value is "Default". This parameter has aliases of Am and Auth. .PARAMETER CertificateThumbprint Specifies the digital public key certificate (X509) of a user account that has permission to perform this action. Enter the certificate thumbprint of the certificate. This parameter has an alias of thumb. .PARAMETER ConfigurationName Specifies the session configuration that is used for the interactive session. .PARAMETER Port Specifies the network port on the remote computer used for this command. To connect to a remote computer, the remote computer must be listening on the port that the connection uses. The default ports are 5985 (the WinRM port for HTTP) and 5986 (the WinRM port for HTTPS). .PARAMETER SessionOption Sets advanced options for the session. Enter a SessionOption object, such as one that you create by using the New-PSSessionOption cmdlet, or a hash table in which the keys are session option names and the values are session option values. .PARAMETER UseSSL Uses the Secure Sockets Layer (SSL) protocol to establish a connection to the remote computer. By default, SSL is not used. .PARAMETER Profile The path to a local file with PowerShell commands to be executed remotely upon connection. Each command in the script must be on a single line. This is a way to run a profile script in the remote session. Here is an profile script example: # Sample remote profile script cd c:\ cls Get-WMIObject Win32_OperatingSystem | Select @{Name="OS";Expression = {$_.Caption}},@{Name="PSVersion";Expression = {$PSVersionTable.PSVersion}} Do not use any block comments in your remote profile script. See examples for additional help. .EXAMPLE PS C:\> New-ISERemoteTab chi-dc01 Create a new remote tab for computer CHI-DC01 with default settings. .EXAMPLE PS C:\> Get-Content c:\work\chi.txt | New-ISERemoteTab -credential mydomain\administrator Create remote tabs for each computer in the list using alternate credentials. This is also the type of command that you could put in your ISE profile script to autocreate remote tabs. .EXAMPLE PS C:\> New-ISERemoteTab dmz-srv01,dmz,srv02,dmz,srv03 -prompt Create remote tabs for each computer and prompt for a unique set of credentials for each. .EXAMPLE PS C:\> New-ISERemoteTab dmz-eft01 -Credential domain\administrator -Authentication CredSSP Create a remote tab for dmz-eft01 with alternate credentials using CredSSP for authentication. .EXAMPLE PS C:\> New-ISERemoteTab dmz-eft01 -ConfigurationName Microsoft.Powershell32 Create a remote tab for dmz-eft01 using the 32-bit configuration settings. The display name for this tab would be "dmz-eft01 Microsoft.Powershell32". .EXAMPLE PS C:\> New-ISERemoteTab chi-core01,chi-core02 -profile c:\scripts\remote.ps1 Create remote tabs for computers CHI-CORE01 and CHI-CORE02. Upon connection remotely run the commands in the local file c:\scripts\remote.ps1. .EXAMPLE PS C:\> import-csv s:\computers.csv | where { test-wsman $_.computername -ErrorAction SilentlyContinue} | Out-GridView -Title "Select computers" -OutputMode Multiple | New-ISERemoteTab -Profile S:\RemoteProfile.ps1 Import a list of computers and filter those that respond to Test-WSMan. This list is then piped to Out-Gridview so that you can select one or more computers to connect to using a remote profile script and current credentials. .NOTES Last Updated: 4 May 2016 Author : Jeff Hicks (http://twitter.com/JeffHicks) Version : 1.4.2 Learn more about PowerShell: http://jdhitsolutions.com/blog/essential-powershell-resources/ **************************************************************** * DO NOT USE IN A PRODUCTION ENVIRONMENT UNTIL YOU HAVE TESTED * * THOROUGHLY IN A LAB ENVIRONMENT. USE AT YOUR OWN RISK. IF * * YOU DO NOT UNDERSTAND WHAT THIS SCRIPT DOES OR HOW IT WORKS, * * DO NOT USE IT OUTSIDE OF A SECURE, TEST SETTING. * **************************************************************** .LINK Enter-PSSession Test-WSMan .INPUTS [string] .OUTPUTS none #> [cmdletbinding(DefaultParameterSetName="Credential")] Param( [Parameter( Position = 0, Mandatory, HelpMessage = "Enter the name of a remote computer", ValueFromPipeline, ValueFromPipelineByPropertyName )] [ValidateNotNullorEmpty()] [Alias("cn")] [string[]]$Computername, [Parameter(ParameterSetName="Credential")] [Alias("RunAs","cred","c")] [ValidateNotNullorEmpty()] [System.Management.Automation.Credential()]$Credential = [System.Management.Automation.PSCredential]::Empty, [Parameter(ParameterSetName="Prompt")] [switch]$PromptForCredential, [ValidateSet("Basic","CredSSP", "Default", "Digest", "Kerberos", "Negotiate", "NegotiateWithImplicitCredential","None")] [Alias('auth','am')] [string]$Authentication, [ValidateNotNullOrEmpty()] [Alias("thumb")] [string]$CertificateThumbprint, [ValidateNotNullOrEmpty()] [string]$ConfigurationName, [ValidateNotNullOrEmpty()] [ValidateRange(1, 2147483647)] [int32]$Port, [System.Management.Automation.Remoting.PSSessionOption]$SessionOption, [Switch]$UseSSL, [ValidateScript({ if (Test-Path $_) { $True } else { Throw "Cannot validate path $_" } })] [string]$Profile ) Begin { Write-Verbose "Starting: $($MyInvocation.Mycommand)" Write-Verbose "Using parameter Set: $($pscmdlet.ParameterSetName)" Write-Verbose "PSBoundParameters" Write-Verbose ($PSBoundParameters | Out-String) #disable PowerShell profiles in new ISE tabs which speeds up the process #thanks for Tobias Weltner for the guidance on this. Write-Verbose "Temporarily disabling PowerShell profiles in new tabs" $type = ([Microsoft.Windows.PowerShell.Gui.Internal.MainWindow].Assembly.GetTypes()).Where({ $_.Name -eq 'PSGInternalHost' }) $currentField = $type.GetField('current', 'NonPublic,Static') $noprofileField = $type.GetField('noProfile', 'NonPublic,Instance') $pshost = $currentField.GetValue($type) $noprofileField.SetValue($pshost,$True) #dynamically build the Enter-PSSession Commmand $cmdstring = "Enter-PSSession -computername {0}" if ($credential.username -AND $pscmdlet.ParameterSetName -eq "credential") { #export credential to a temporary local file because each new tab is a new session $credPath = [System.IO.Path]::GetTempFileName() Write-Verbose "Exporting credential for $($credential.username) to $credpath" $credential | Export-Clixml -Path $credpath $cmdstring+= " -credential (Import-Clixml -path $credpath)" } #export session option to cliXML so that it can be read into the scriptblock if ($SessionOption) { $optPath = [System.IO.Path]::GetTempFileName() Write-Verbose "Exporting session options to $optPath" $sessionOption | Export-Clixml -Path $optPath $cmdstring += " -SessionOption (Import-cliXML -path $optPath)" } if ($Authentication) {$cmdstring += " -authentication $Authentication"} if ($CertificateThumbprint) {$cmdstring += " -CertificateThumbprint $CertificateThumbprint"} if ($ConfigurationName) {$cmdstring += " -configurationname $ConfigurationName"} if ($Port) {$cmdstring += " -Port $Port"} if ($UseSSL) {$cmdstring += " -UseSSL"} } #begin Process { Write-Verbose "PSBoundParameters in Process" Write-Verbose ($PSBoundParameters | Out-String) #copy bound parameters to a new hashtable $testParams = $PSBoundParameters #remove invalid parameters if ($profile) { #remove profile parameter since Test-WSMan won't recognize it $testParams.remove("profile") | Out-Null } if ($SessionOption) { $testParams.remove("sessionoption") | Out-Null } if ($PromptForCredential) { $testParams.remove("promptforCredential") | Out-Null } #Using the ForEach() method to eke out a little bit better performance #when processing multiple computer names ($Computername).Foreach({ $computer = $_ Write-Verbose "Processing: $computer" #insert each computername $cmd = $cmdstring -f $computer #insert the current computer nto the parameters for Test-WSMan $testParams.Computername = $computer #remove configurationname from Test-WSMan $testparams.Remove("ConfigurationName") | Out-Null #Verify Computer is accessible with Test-WSMan Try { Test-WSMan @testParams -ErrorAction Stop | Out-Null $newtab = $psise.powershelltabs.Add() #change the tab name $newTab.DisplayName = $Computer.ToUpper() if ($ConfigurationName){$newtab.DisplayName += " $ConfigurationName"} #wait for new tab to be created Do { Start-Sleep -Milliseconds 10 } until ($newTab.CanInvoke) if ($PromptForCredential) { Write-Verbose "Prompting for credential" $NewTab.invoke("`$cred = Get-Credential -message 'Enter a credential for $($newtab.DisplayName)' -username $env:userdomain\$env:username") Do { Start-Sleep -Milliseconds 10 } until ($newTab.CanInvoke) $cmd+= ' -credential $cred' } #if prompt for credential Write-Verbose "Executing: $cmd" $newtab.Invoke($cmd) Do { #wait until ready start-Sleep -Milliseconds 10 } until ($newTab.CanInvoke) #run some initial commands in each remote session if ($profile) { Write-Verbose "Launching commands from $profile" #get contents of profile script where there are words but no comments Get-Content $profile | where {$_ -match "\w+" -AND $_ -notmatch "#"} | foreach { Write-Verbose "[$($newTab.Displayname)] Invoking $_" $newTab.Invoke($_) #wait for command to complete Do { Start-Sleep -Milliseconds 10 } until ($newTab.CanInvoke) } #foreach command } #if profile script } #Try Catch { Write-Warning "Can't create remote tab to $computer. $($_.exception.Message)." } }) #foreach computer } #process End { #re-enable PowerShell profiles Write-Verbose "Re-enabling PowerShell ISE profiles" $noprofileField.SetValue($pshost,$False) #delete credential file if it exists if ($credpath -AND (Test-Path -path $credPath)) { Write-Verbose "Deleting $credpath" del $credPath -Force } #delete session option file if it exists if ($optpath -AND (Test-Path -path $optPath)) { Write-Verbose "Deleting $optpath" del $optPath -Force } Write-Verbose "Ending: $($MyInvocation.Mycommand)" } #end } #end function #define an alias Set-Alias -Name nrt -Value New-ISERemoteTab |