All messages posted to this blog are provided "AS IS" with no warranties, and confer no rights.
Information on unreleased products are subject to change without notice.
Dates related to unreleased products are estimates and are subject to change without notice.
The content of this site are personal opinions and might not represent the Microsoft Corporation view.
The information contained in this blog represents my view on the issues discussed as of the date of publication.
You should not consider older, out-of-date posts to reflect my current thoughts and opinions.
© Copyright 2004-2012 by Jose Barreto. All rights reserved.
Follow @josebarreto on Twitter for updates on new blog posts.
As I continue to experiment with PowerShell v2 in Windows Server 2008 R2, I will share some of what I learn here on the blog. This time I am focusing on PowerShell Remoting. If you never played with PowerShell before, please start by reading http://blogs.technet.com/josebda/archive/2009/07/25/experimenting-with-powershell.aspx and http://blogs.technet.com/josebda/archive/2009/08/09/experimenting-with-powershell-cmdlets-snap-ins-and-modules.aspx
Remoting
In general, “remoting” relates to the ability to query another computer or execute tasks against these remote computers. Many command line tools can act upon a remote server (using something like an RPC). You also can always use RDP (Remote Desktop Protocol) to bring an entire remote desktop to you, but this does not help much if you’re trying to interact with a large set of servers. PowerShell can help a lot with that. When we talk about “PowerShell Remoting”, we’re usually referring to the ability to sit in the comfort of your client (running Windows 7, for instance), open a PowerShell window and issue commands that interact with a remote server (running Windows Server 2008 R2, for instance). This can also function as the basics to create interesting PowerShell scripts that gather information from a set of servers and/or perform tasks involving multiple servers. This could including compiling a list of all servers in a domain running the DHCP server service, generating a report with the free space on system volume for you domain controllers or pointing all servers that do not have a specific hotfix applied.
In general, “remoting” relates to the ability to query another computer or execute tasks against these remote computers. Many command line tools can act upon a remote server (using something like an RPC). You also can always use RDP (Remote Desktop Protocol) to bring an entire remote desktop to you, but this does not help much if you’re trying to interact with a large set of servers. PowerShell can help a lot with that.
When we talk about “PowerShell Remoting”, we’re usually referring to the ability to sit in the comfort of your client (running Windows 7, for instance), open a PowerShell window and issue commands that interact with a remote server (running Windows Server 2008 R2, for instance). This can also function as the basics to create interesting PowerShell scripts that gather information from a set of servers and/or perform tasks involving multiple servers. This could including compiling a list of all servers in a domain running the DHCP server service, generating a report with the free space on system volume for you domain controllers or pointing all servers that do not have a specific hotfix applied.
Cmdlets take take a –computername parameter
A number of PowerShell commandlets can act on a remote server by simply using a –computername parameter (it typically can be shortened to –cn). These commandlets will use DCOM/RPC to communicate with the remote computer and execute the commands. The results are provided back to you in the PowerShell pipeline, in the same way it happens for local command. Here’s a list of some of the PowerShell commandlets that support this parameter: Get-Service Get-Process Get-HotFix Get-Counter Get-EventLog Get-WinEvent Get-WmiObject To help you understand how these cmdlets work with the computername parameter, I am adding a few examples below. Please note that sometimes I will show the same command line twice, once in a more verbose version and the other in a more succinct version using aliases. The output for two equivalent comment is the same and is showed only once.
A number of PowerShell commandlets can act on a remote server by simply using a –computername parameter (it typically can be shortened to –cn). These commandlets will use DCOM/RPC to communicate with the remote computer and execute the commands. The results are provided back to you in the PowerShell pipeline, in the same way it happens for local command. Here’s a list of some of the PowerShell commandlets that support this parameter:
To help you understand how these cmdlets work with the computername parameter, I am adding a few examples below. Please note that sometimes I will show the same command line twice, once in a more verbose version and the other in a more succinct version using aliases. The output for two equivalent comment is the same and is showed only once.
Example: Find out the status of the SQL Server service running on a remote computer
Get-Service MSSQLServer -ComputerName josebda-s0gsv MSSQLServer –cn josebda-s0 Status Name DisplayName------ ---- -----------Running MSSQLSERVER SQL Server (MSSQLSERVER)
Get-Service MSSQLServer -ComputerName josebda-s0gsv MSSQLServer –cn josebda-s0
Status Name DisplayName------ ---- -----------Running MSSQLSERVER SQL Server (MSSQLSERVER)
Example: Get a list of hotfixes installed on a remote computer
Get-Hotfix -computername josebda-s0 | Select HotfixID, Description, InstalledOn | Sort-Object InstalledOnGet-Hotfix –cn josebda-s0 | Select HotfixID, Description, InstalledOn | sort InstalledOn HotfixID Description InstalledOn-------- ----------- -----------KB978207 Update 3/28/2010 12:00:00 AMKB975560 Security Update 3/28/2010 12:00:00 AMKB978262 Security Update 3/28/2010 12:00:00 AMKB978251 Security Update 3/28/2010 12:00:00 AMKB972270 Security Update 3/28/2010 12:00:00 AMKB971468 Security Update 3/28/2010 12:00:00 AMKB975467 Hotfix 3/28/2010 12:00:00 AMKB974571 Security Update 3/28/2010 12:00:00 AM
Get-Hotfix -computername josebda-s0 | Select HotfixID, Description, InstalledOn | Sort-Object InstalledOnGet-Hotfix –cn josebda-s0 | Select HotfixID, Description, InstalledOn | sort InstalledOn
HotfixID Description InstalledOn-------- ----------- -----------KB978207 Update 3/28/2010 12:00:00 AMKB975560 Security Update 3/28/2010 12:00:00 AMKB978262 Security Update 3/28/2010 12:00:00 AMKB978251 Security Update 3/28/2010 12:00:00 AMKB972270 Security Update 3/28/2010 12:00:00 AMKB971468 Security Update 3/28/2010 12:00:00 AMKB975467 Hotfix 3/28/2010 12:00:00 AMKB974571 Security Update 3/28/2010 12:00:00 AM
Example: Use WMI to get a list of volumes (including size and free space) on a remote computer
Get-WmiObject Win32_LogicalDisk -ComputerName josebda1 | Format-Tablegwmi Win32_LogicalDisk –cn josebda1 | ft DeviceID DriveType ProviderName FreeSpace Size VolumeName-------- --------- ------------ --------- ---- ----------C: 3 62085390336 119926681600D: 5E: 5
Get-WmiObject Win32_LogicalDisk -ComputerName josebda1 | Format-Tablegwmi Win32_LogicalDisk –cn josebda1 | ft
DeviceID DriveType ProviderName FreeSpace Size VolumeName-------- --------- ------------ --------- ---- ----------C: 3 62085390336 119926681600D: 5E: 5
This example showing the use of WMI objects from a remote computer opens a really wide set of possibilities, since there are a lot ofof WMI providers out there…
Protocols and Permissions
Also note that, while these are PowerShell commandlets using a –computername parameter execute on a remote computer, they are not technically considered “PowerShell Remoting”. They actually use DCOM/RPC to execute. You do want to make sure that your management computer can talk to the server and the account you’re using has the permissions to execute RPCs. If you can’t connect to that server (if the firewall does not allow RPC connections, for instance) or you do not have the right permissions, you might see an error message like: Get-Service –ComputerName josebda-s0gsv -cn josebda-s0 Get-Service : Cannot open Service Control Manager on computer 'josebda-s0'. This operation might require other privileges.At line:1 char:12+ get-service <<<< -cn josebda-s0 + CategoryInfo : NotSpecified: (:) [Get-Service], InvalidOperationException + FullyQualifiedErrorId : System.InvalidOperationException,Microsoft.PowerShell.Commands.GetServiceCommand
Also note that, while these are PowerShell commandlets using a –computername parameter execute on a remote computer, they are not technically considered “PowerShell Remoting”. They actually use DCOM/RPC to execute. You do want to make sure that your management computer can talk to the server and the account you’re using has the permissions to execute RPCs. If you can’t connect to that server (if the firewall does not allow RPC connections, for instance) or you do not have the right permissions, you might see an error message like:
Get-Service –ComputerName josebda-s0gsv -cn josebda-s0
Get-Service : Cannot open Service Control Manager on computer 'josebda-s0'. This operation might require other privileges.At line:1 char:12+ get-service <<<< -cn josebda-s0 + CategoryInfo : NotSpecified: (:) [Get-Service], InvalidOperationException + FullyQualifiedErrorId : System.InvalidOperationException,Microsoft.PowerShell.Commands.GetServiceCommand
Enable-PSRemoting
The other two ways I will describe are the proper “PowerShell Remoting” features, which use WS-Management (also referred to as Windows Remote Management or WinRM). In order to use them, you need to make sure you have a listener service properly configure on the remote machine you will be communicating with. All you need to do is run the Enable-PSRemoting commandlet and confirm at the prompts. See the example below: Enable-PSRemoting WinRM Quick ConfigurationRunning command "Set-WSManQuickConfig" to enable this machine for remote management through WinRM service.This includes: 1. Starting or restarting (if already started) the WinRM service 2. Setting the WinRM service type to auto start 3. Creating a listener to accept requests on any IP address 4. Enabling firewall exception for WS-Management traffic (for http only). Do you want to continue?[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"): <ENTER> WinRM has been updated to receive requests.WinRM service type changed successfully.WinRM service started. WinRM has been updated for remote management.Created a WinRM listener on HTTP://* to accept WS-Man requests to any IP on this machine.WinRM firewall exception enabled. ConfirmAre you sure you want to perform this action?Performing operation "Registering session configuration" on Target "Session configuration "Microsoft.PowerShell32" isnot found. Running command "Register-PSSessionConfiguration Microsoft.PowerShell32 -processorarchitecture x86 -force"to create "Microsoft.PowerShell32" session configuration. This will restart WinRM service.".[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"): <ENTER> This needs to be performed only once for every host you intend to remotely query or configure using the two sets of commands I will describe next. There’s a bit of a chicken-and-egg problem here, since you cannot run “Enable-PSRemoting” remotely and the default configuration has this disabled. You need to somehow overcome this by making this your default server configuration, logging locally at least once to configure this or using Remote Desktop (RDP) to run it.
The other two ways I will describe are the proper “PowerShell Remoting” features, which use WS-Management (also referred to as Windows Remote Management or WinRM). In order to use them, you need to make sure you have a listener service properly configure on the remote machine you will be communicating with. All you need to do is run the Enable-PSRemoting commandlet and confirm at the prompts. See the example below:
WinRM Quick ConfigurationRunning command "Set-WSManQuickConfig" to enable this machine for remote management through WinRM service.This includes: 1. Starting or restarting (if already started) the WinRM service 2. Setting the WinRM service type to auto start 3. Creating a listener to accept requests on any IP address 4. Enabling firewall exception for WS-Management traffic (for http only).
Do you want to continue?[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"): <ENTER>
WinRM has been updated to receive requests.WinRM service type changed successfully.WinRM service started.
WinRM has been updated for remote management.Created a WinRM listener on HTTP://* to accept WS-Man requests to any IP on this machine.WinRM firewall exception enabled.
ConfirmAre you sure you want to perform this action?Performing operation "Registering session configuration" on Target "Session configuration "Microsoft.PowerShell32" isnot found. Running command "Register-PSSessionConfiguration Microsoft.PowerShell32 -processorarchitecture x86 -force"to create "Microsoft.PowerShell32" session configuration. This will restart WinRM service.".[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"): <ENTER>
This needs to be performed only once for every host you intend to remotely query or configure using the two sets of commands I will describe next. There’s a bit of a chicken-and-egg problem here, since you cannot run “Enable-PSRemoting” remotely and the default configuration has this disabled. You need to somehow overcome this by making this your default server configuration, logging locally at least once to configure this or using Remote Desktop (RDP) to run it.
Use Invoke-Command
Once you have run Enable-PSRemoting, you can use Invoke-Command to run any PowerShell command to execute commands agains a remote computer. It’s that simple. As with a locally executed command, you get the resulting objects in your pipeline. PowerShell remoting takes care of serializing the objects over the wire and reassembling them on your client. Here are a few examples.
Example: Getting a list of environment variables starting with the letter C in a remote computer
Invoke-Command josebda-s0 {Get-ChildItem Env:\C*}icm josebda-s0 {dir env:\c*} Name Value PSComputerName---- ----- --------------COMPUTERNAME JOSEBDA-S0 josebda-s0CommonProgramW6432 C:\Program Files\Common Files josebda-s0CommonProgramFiles(x86) C:\Program Files (x86)\Common Files josebda-s0CommonProgramFiles C:\Program Files\Common Files josebda-s0ComSpec C:\Windows\system32\cmd.exe josebda-s0
Invoke-Command josebda-s0 {Get-ChildItem Env:\C*}icm josebda-s0 {dir env:\c*}
Name Value PSComputerName---- ----- --------------COMPUTERNAME JOSEBDA-S0 josebda-s0CommonProgramW6432 C:\Program Files\Common Files josebda-s0CommonProgramFiles(x86) C:\Program Files (x86)\Common Files josebda-s0CommonProgramFiles C:\Program Files\Common Files josebda-s0ComSpec C:\Windows\system32\cmd.exe josebda-s0
Example: Getting a list of PowerShell drives on a remote computer
icm josebda-s0 {Get-PSDrive} | Select Name, Root, Free, Used Name Root Free Used---- ---- ---- ----AliasC C:\ 227056844800 22895357952cert \D D:\ 0EnvFunctionHKCU HKEY_CURRENT_USERHKLM HKEY_LOCAL_MACHINEVariableWSMan
icm josebda-s0 {Get-PSDrive} | Select Name, Root, Free, Used
Name Root Free Used---- ---- ---- ----AliasC C:\ 227056844800 22895357952cert \D D:\ 0EnvFunctionHKCU HKEY_CURRENT_USERHKLM HKEY_LOCAL_MACHINEVariableWSMan
Example: Check the status of the Spooler service on a remote computer
Get-Service Spooler -ComputerName josebda-s0gsv Spooler -cn josebda-s0 Status Name DisplayName------ ---- -----------Running Spooler Print Spooler Invoke-Command josebda-s0 {Get-Service Spooler}icm josebda-s0 {gsv "Spooler"} Status Name DisplayName PSComputerName------ ---- ----------- --------------Running Spooler Print Spooler josebda-s0
Get-Service Spooler -ComputerName josebda-s0gsv Spooler -cn josebda-s0
Status Name DisplayName------ ---- -----------Running Spooler Print Spooler
Invoke-Command josebda-s0 {Get-Service Spooler}icm josebda-s0 {gsv "Spooler"}
Status Name DisplayName PSComputerName------ ---- ----------- --------------Running Spooler Print Spooler josebda-s0
As you can see, for commands that support the –computername parameter, you can use that form or choose to use Invoke-Command instead. The results should be very similar, but the difference is that you are using a different protocol over the wire (DCOM/RPC instead of WinRM).
Interactive Remoting
If you intend to run a set of commands on a specific computer, you can use Interactive remoting to create a remote session and get a new prompt where all commands go to that remote computer. This is a convenient way to explore the configuration of a remote computer, but not so useful when creating a batch file. You start by using an Enter-PSSession command (or simply ETSN), then you get a new prompt to execute the remote commands. When you’re done, you close the remote session using Exit-PSSession (or simply EXSN or EXIT). Here’s an example: PS C:\Windows\system32> Enter-PSSession josebda-s0[josebda-s0]: PS C:\Windows\system32> dir env:\c* Name Value---- -----COMPUTERNAME JOSEBDA-S0CommonProgramW6432 C:\Program Files\Common FilesCommonProgramFiles(x86) C:\Program Files (x86)\Common FilesCommonProgramFiles C:\Program Files\Common FilesComSpec C:\Windows\system32\cmd.exe [josebda-s0]: PS C:\Windows\system32> dir C:\ Directory: C:\ Mode LastWriteTime Length Name---- ------------- ------ ----d---- 7/13/2009 8:20 PM PerfLogsd-r-- 3/30/2010 9:23 AM Program Filesd-r-- 3/29/2010 6:49 AM Program Files (x86)d---- 3/28/2010 9:15 PM Tempd-r-- 3/28/2010 2:28 PM Usersd---- 3/30/2010 3:45 PM Windows [josebda-s0]: PS C:\Windows\system32> Exit-PSSessionPS C:\Windows\system32> You can even create a persistent session using the New-PSSession command, which you can then use with Enter-PSSession. This is useful if you intend to keep the session open and re-enter multiple times.
If you intend to run a set of commands on a specific computer, you can use Interactive remoting to create a remote session and get a new prompt where all commands go to that remote computer. This is a convenient way to explore the configuration of a remote computer, but not so useful when creating a batch file. You start by using an Enter-PSSession command (or simply ETSN), then you get a new prompt to execute the remote commands. When you’re done, you close the remote session using Exit-PSSession (or simply EXSN or EXIT). Here’s an example:
PS C:\Windows\system32> Enter-PSSession josebda-s0[josebda-s0]: PS C:\Windows\system32> dir env:\c*
Name Value---- -----COMPUTERNAME JOSEBDA-S0CommonProgramW6432 C:\Program Files\Common FilesCommonProgramFiles(x86) C:\Program Files (x86)\Common FilesCommonProgramFiles C:\Program Files\Common FilesComSpec C:\Windows\system32\cmd.exe
[josebda-s0]: PS C:\Windows\system32> dir C:\
Directory: C:\
Mode LastWriteTime Length Name---- ------------- ------ ----d---- 7/13/2009 8:20 PM PerfLogsd-r-- 3/30/2010 9:23 AM Program Filesd-r-- 3/29/2010 6:49 AM Program Files (x86)d---- 3/28/2010 9:15 PM Tempd-r-- 3/28/2010 2:28 PM Usersd---- 3/30/2010 3:45 PM Windows
[josebda-s0]: PS C:\Windows\system32> Exit-PSSessionPS C:\Windows\system32>
You can even create a persistent session using the New-PSSession command, which you can then use with Enter-PSSession. This is useful if you intend to keep the session open and re-enter multiple times.
Multiple servers at once
By now you should probably be convinced that executing commands remotely with PowerShell is very convenient. However, you can take it one step further by executing the same command in multiple servers in a single line. And you still get a single set of objects in the pipeline as a result. As with most things in PowerShell, there are a few different ways to do it. First, you can provide a set of names (separated by comma) in your –computername parameter. You can also create a variable that contains a set of names and use that variable. You can even store the computernames in a text file and use the Get-Content commandlet (or the alias Type) to bring that data in as part of your commandline. This last one can be done by including the Type command in parenthesis, right after the –computername, ). The same options apply to Invoke-Command. There is a tricky part about doing this, which is making sure you get a property that tells which computer returned that specific object in the resulting set. There’s usually a way to tell, but this is not always the same property. The next set of examples explores the possibilities for running commands in multiple server in the same line and include more elaborate command lines. I hope you enjoy them.
By now you should probably be convinced that executing commands remotely with PowerShell is very convenient. However, you can take it one step further by executing the same command in multiple servers in a single line. And you still get a single set of objects in the pipeline as a result.
As with most things in PowerShell, there are a few different ways to do it. First, you can provide a set of names (separated by comma) in your –computername parameter. You can also create a variable that contains a set of names and use that variable. You can even store the computernames in a text file and use the Get-Content commandlet (or the alias Type) to bring that data in as part of your commandline. This last one can be done by including the Type command in parenthesis, right after the –computername, ). The same options apply to Invoke-Command.
There is a tricky part about doing this, which is making sure you get a property that tells which computer returned that specific object in the resulting set. There’s usually a way to tell, but this is not always the same property.
The next set of examples explores the possibilities for running commands in multiple server in the same line and include more elaborate command lines. I hope you enjoy them.
Example: Get a list of all hard drives (drive type is 3) for a set of computers. Multiple names passed directly in the command line
Get-WmiObject Win32_LogicalDisk -ComputerName josebda1, josebda-s0, josebda-s1 | Where-Object { $_.DriveType -eq 3 } | select SystemName, DeviceID, Size, FreeSpace | Format-Tablegwmi Win32_LogicalDisk -cn josebda1, josebda-s0, josebda-s1 | ? { $_.DriveType -eq 3 } | Select SystemName, DeviceID, Size, FreeSpace | ft SystemName DeviceID Size FreeSpace---------- -------- ---- ---------JOSEBDA1 C: 119926681600 62085210112JOSEBDA-S0 C: 249952202752 227057037312JOSEBDA-S1 C: 249952202752 222086516736
Get-WmiObject Win32_LogicalDisk -ComputerName josebda1, josebda-s0, josebda-s1 | Where-Object { $_.DriveType -eq 3 } | select SystemName, DeviceID, Size, FreeSpace | Format-Tablegwmi Win32_LogicalDisk -cn josebda1, josebda-s0, josebda-s1 | ? { $_.DriveType -eq 3 } | Select SystemName, DeviceID, Size, FreeSpace | ft
SystemName DeviceID Size FreeSpace---------- -------- ---- ---------JOSEBDA1 C: 119926681600 62085210112JOSEBDA-S0 C: 249952202752 227057037312JOSEBDA-S1 C: 249952202752 222086516736
Example: Get a list of all SMB shares for a set of servers. List of computer names stored in a variable ($a) that’s passed in the command line.
$a="josebda1", "josebda-s0", "josebda-s1"Get-WmiObject Win32_Share -ComputerName $a | Select __Server, Name, Path, Descriptiongwmi Win32_Share -cn $a | Select __Server, Name, Path, Description __SERVER Name Path Description-------- ---- ---- -----------JOSEBDA1 ADMIN$ C:\Windows Remote AdminJOSEBDA1 C$ C:\ Default shareJOSEBDA1 IPC$ Remote IPCJOSEBDA-S0 ADMIN$ C:\Windows Remote AdminJOSEBDA-S0 C$ C:\ Default shareJOSEBDA-S0 IPC$ Remote IPCJOSEBDA-S0 MSSQLSERVER \\?\GLOBALROOT\Device\RsFx... SQL Server FILESTREAM shareJOSEBDA-S1 ADMIN$ C:\Windows Remote AdminJOSEBDA-S1 C$ C:\ Default shareJOSEBDA-S1 IPC$ Remote IPCJOSEBDA-S1 josebda-dfs C:\DFSRoots\josebda-dfsJOSEBDA-S1 Software C:\Software
$a="josebda1", "josebda-s0", "josebda-s1"Get-WmiObject Win32_Share -ComputerName $a | Select __Server, Name, Path, Descriptiongwmi Win32_Share -cn $a | Select __Server, Name, Path, Description
__SERVER Name Path Description-------- ---- ---- -----------JOSEBDA1 ADMIN$ C:\Windows Remote AdminJOSEBDA1 C$ C:\ Default shareJOSEBDA1 IPC$ Remote IPCJOSEBDA-S0 ADMIN$ C:\Windows Remote AdminJOSEBDA-S0 C$ C:\ Default shareJOSEBDA-S0 IPC$ Remote IPCJOSEBDA-S0 MSSQLSERVER \\?\GLOBALROOT\Device\RsFx... SQL Server FILESTREAM shareJOSEBDA-S1 ADMIN$ C:\Windows Remote AdminJOSEBDA-S1 C$ C:\ Default shareJOSEBDA-S1 IPC$ Remote IPCJOSEBDA-S1 josebda-dfs C:\DFSRoots\josebda-dfsJOSEBDA-S1 Software C:\Software
Example: Get a list of PowerShell drives for a set of computers. List of computer names stored in a file (serverlist.txt) that’s passed in the command line via Get-Content (4 different forms!?).
type serverlist.txtGet-Content serverlist.txtjosebda-s0josebda-s1Invoke-Command (Get-Content "serverlist.txt") {Get-PSDrive}icm (type "serverlist.txt") {Get-PSDrive}Get-Content serverlist.txt | ForEach-Object { Invoke-Command $_ {Get-PSDrive}}type serverlist.txt | % {icm $_ {Get-PSDrive}} Name Used (GB) Free (GB) Provider Root CurrentLocation PSComputerName---- --------- --------- -------- ---- --------------- --------------Alias josebda-s1C 25.96 206.83 C:\ ...ows\system32 josebda-s1cert \ josebda-s1D D:\ josebda-s1Env josebda-s1Function josebda-s1HKCU HKEY_CURRENT_USER josebda-s1HKLM HKEY_LOCAL_MACHINE josebda-s1Variable josebda-s1WSMan josebda-s1Alias josebda-s0C 21.36 211.42 C:\ ...ows\system32 josebda-s0cert \ josebda-s0D D:\ josebda-s0Env josebda-s0Function josebda-s0HKCU HKEY_CURRENT_USER josebda-s0HKLM HKEY_LOCAL_MACHINE josebda-s0Variable josebda-s0WSMan josebda-s0
type serverlist.txtGet-Content serverlist.txtjosebda-s0josebda-s1Invoke-Command (Get-Content "serverlist.txt") {Get-PSDrive}icm (type "serverlist.txt") {Get-PSDrive}Get-Content serverlist.txt | ForEach-Object { Invoke-Command $_ {Get-PSDrive}}type serverlist.txt | % {icm $_ {Get-PSDrive}}
Name Used (GB) Free (GB) Provider Root CurrentLocation PSComputerName---- --------- --------- -------- ---- --------------- --------------Alias josebda-s1C 25.96 206.83 C:\ ...ows\system32 josebda-s1cert \ josebda-s1D D:\ josebda-s1Env josebda-s1Function josebda-s1HKCU HKEY_CURRENT_USER josebda-s1HKLM HKEY_LOCAL_MACHINE josebda-s1Variable josebda-s1WSMan josebda-s1Alias josebda-s0C 21.36 211.42 C:\ ...ows\system32 josebda-s0cert \ josebda-s0D D:\ josebda-s0Env josebda-s0Function josebda-s0HKCU HKEY_CURRENT_USER josebda-s0HKLM HKEY_LOCAL_MACHINE josebda-s0Variable josebda-s0WSMan josebda-s0
By now you should have a few additional ideas in mind on how to put PowerShell to good use. What are you waiting for? Go write some scripts… :-)
Very useful and a nice intro to remoting in PowerShell. Something I've been meaning to do for a while