Let’s take a look at the Invoke-ScriptBlock
command. Notice that it has a -ComputerName
parameter. Hmmm . . . does that mean it can run commands on other hosts too? After a bit of experimenting, you’ll discover that’s exactly what it does. How many other commands have the ability to connect to remote machines? While there is not a way to obtain a concrete number to answer this question, there are quite a lot.
What we’ve realized is that PowerShell’s creators are a bit lazy—and that’s a good thing. Because they didn’t want to have to code a -HostName
parameter for every single cmdlet, they created a shell-wide system called remoting. This system enables you to run any cmdlet on a remote computer. In fact, you can even run commands that exist on the remote computer but that don’t exist on your own computer—meaning you don’t always have to install every administrative cmdlet on your workstation. This remoting system is powerful, and it offers interesting administrative capabilities.
Note Remoting is a huge, complex technology. We introduce you to it in this chapter and cover usage scenarios that you’ll deal with 80% to 90% of the time. But we can’t cover it all, so in the “Further exploration” section at the end of this chapter, we point you to a must-have resource that covers remoting’s configuration options.
Remote PowerShell works somewhat similarly to Telnet and other age-old remote-control technologies. When you run a command, it’s running on the remote computer—only the results of that command come back to your computer.
PowerShell uses a communications protocol called Web Services for Management (WSMan). WSMan operates entirely over HTTP or HTTPS (HTTP by default), making it easy to route through firewalls if necessary (because each of those protocols uses a single port to communicate). Microsoft’s implementation of WSMan comes in the form of a background service, Windows Remote Management (WinRM). WinRM is installed by default on Windows 10 devices and Server 2012 and up. By default, these services are disabled but can easily be enabled individually or by group policy.
As you can guess, WSMan and WinRM are Windows-only services. So in order for PowerShell to have remoting capabilities, the team decided that it would be best to use the industry standard Secure Shell (SSH). SSH makes it easy to route through firewalls if necessary (because that protocol uses a single port to communicate) and has been used by Linux professionals for decades. Microsoft has ported OpenSSH to Windows, so you can even use this to remote into Windows.
You’ve already learned that PowerShell cmdlets all produce objects as their output. When you run a remote command, its output objects need to be put into a form that can be easily transmitted over a network. XML, it turns out, is an excellent way to do that, so PowerShell automatically serializes those output objects into XML. The XML is transmitted across the network and is then deserialized on your computer back into objects that you can work with inside PowerShell. Serialization and deserialization are really just a form of format conversion: from objects to XML (serialization), and from XML to objects (deserialization).
Why should you care how this output is returned? Because those serialized-then-deserialized objects are only snapshots, of sorts; they don’t update themselves continually. For example, if you were to get the objects that represent the processes running on a remote computer, what you’d get back would be accurate for only the exact point in time at which those objects were generated. Values such as memory usage and CPU utilization won’t be updated to reflect subsequent conditions. In addition, you can’t tell the deserialized objects to do anything—you can’t instruct one to stop itself, for example.
Those are basic limitations of remoting, but they don’t stop you from doing some amazing stuff. In fact, you can tell a remote process to stop itself, but you have to be clever about it. We’ll show you how later in this chapter. To make remoting work, you have two basic requirements:
Both your computer and the one you want to send commands to must be running PowerShell v7.1 or later.
Ideally, both computers need to be members of the same domain, or of trusted/ trusting domains. It’s possible to get remoting to work outside a domain, but it’s trickier, and we don’t cover it in this chapter. To learn more about that scenario, open PowerShell and run help
about_remote_troubleshooting
.
Try it Now We hope you’ll be able to follow along with some of the examples in this chapter. To participate, you’ll ideally have a second test computer (or a virtual machine) that’s in the same Active Directory domain as the test computer you’ve been using up to this point. You can run any version of Windows on that second computer, provided you have PowerShell v7.1 or later installed. If you are using two Windows devices, it will make your life a lot easier if they are part of the same domain. If you can’t set up an additional computer or virtual machine, use localhost
to create remoting connections to your current computer. You’re still using remoting, but it isn’t as exciting to be “remote controlling” the computer at which you’re sitting.
Let’s spend some time getting SSH set up in your environment.
On the computer, make sure that the SSH server and client are installed. On Ubuntu, these are the instructions:
For macOS, the client is installed by default. Here is the command to enable the server:
Next, we need to install the module that enables PSRP over SSH:
Then, run the command to enable PSRP over SSH:
Next, you need to restart the OpenSSH service. On Ubuntu, this is the command to restart the service:
On macOS, this is the command:
SSH can run on Windows desktops and servers as well. In fact, you can disable WinRM if you really want to (we don’t suggest you do that). Most likely, if you are using SSH for remoting on a Windows device, you are either remoting to or from a Linux or macOS device.
Install the OpenSSH client and server:
Add-WindowsCapability -Online -Name OpenSSH.Client~~~~0.0.1.0 Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
Here is the initial configuration of the SSH server:
Confirm the firewall rule is configured. It should be created automatically by setup:
There should be a firewall rule named OpenSSH-Server-In-TCP
, which should be enabled. Configure and edit the sshd_config file located at $env:ProgramDatassh
on the target machine (figure 13.1).
Verify that password authentication is enabled by removing the #
sign:
Add the Subsystem
for PowerShell. You can see that we are using the 8.3 short names for the file paths that contain spaces.
The 8.3 short name for the Program Files
folder in Windows is usually Progra~1
. However, you can use the following command to make sure:
Get-CimInstance Win32_Directory -Filter 'Name="C:\Program Files"' | ➥ Select-Object EightDotThreeFileName
An optional enable-key authentication is
Let’s talk about SSH, because you’re going to have to configure it in order to use remoting. Once again, you need to configure PSRP over SSH—and PowerShell remoting—on only those computers that will receive incoming commands. In most of the environments we’ve worked in, the administrators have enabled remoting on every computer. Doing so gives you the ability to remote into client desktop and laptop computers in the background (meaning the users of those computers won’t know you’re doing so), which can be tremendously useful.
SSH allows multiple subsystems to register. This allows different protocols to work over the same port. When you enable SSH remoting, PowerShell registers as a subsystem, and incoming connections from PSRP are routed to that subsystem. Figure 13.2 illustrates how the pieces fit together.
As shown, you can have dozens or even hundreds of sshd
subsystems on your system. Each endpoint can point to a different application.
Figure 13.2 also illustrates the sshd
listener. sshd
acts as a listener sitting and waiting for incoming network traffic—kind of like a web server listening for incoming requests. A listener “listens” on a specific port and on a specific IP address.
Try it Now Go ahead and enable remoting on your second computer (or on the first one, if that’s the only one you have to work with). If you receive an error message when you enable remoting, stop and figure it out.
Let’s talk about WinRM, because you’re going to have to configure it in order to use remoting. Once again, you need to configure WinRM—and PowerShell remoting—on only those computers that will receive incoming commands. In most of the environments we’ve worked in, the administrators have enabled remoting on every Windows-based computer (keep in mind that PowerShell and remoting are supported all the way back to Windows XP). Doing so gives you the ability to remote into client desktop and laptop computers in the background (meaning the users of those computers won’t know you’re doing so), which can be tremendously useful.
WinRM isn’t unique to PowerShell. Microsoft is starting to use it for more and more administrative communications—even things that use other protocols today. With that in mind, Microsoft made WinRM capable of routing traffic to multiple administrative applications—not only PowerShell. WinRM acts as a dispatcher: when traffic comes in, WinRM decides which application needs to deal with that traffic. All WinRM traffic is tagged with the name of a recipient application, and those applications must register as endpoints with WinRM so that WinRM will listen for incoming traffic on their behalf. This means you need to not only enable WinRM, but also tell PowerShell to register as an endpoint with WinRM. Figure 13.3 illustrates how the pieces fit together.
As shown, you can have dozens or even hundreds of WinRM endpoints on your system (PowerShell calls them session configurations). Each endpoint can point to a different application, and you can even have endpoints that point to the same application but provide different permissions and functionality. For example, you could create a PowerShell endpoint that allows only one or two commands, and make it available to specific users in your environment. We don’t dive that deep into remoting in this chapter, but we do later in the book.
Figure 13.3 also illustrates the WinRM listener, which in the figure is of the HTTP variety. A listener sits and waits for incoming network traffic on behalf of WinRM—kind of like a web server listening for incoming requests. A listener “listens” on a specific port and on a specific IP address, although the default listener created by Enable-PSRemoting
listens on all local IP addresses.
The listener connects to the defined endpoint. One way to create an endpoint is to open a copy of PowerShell—making sure that you’re running it as an administrator—and run the Enable-PSRemoting
cmdlet. You might sometimes see references to a different cmdlet, called Set-WSManQuickConfig
. You don’t need to run that one; Enable-PSRemoting
will call it for you, and Enable-PSRemoting
performs a few extra steps that are necessary to get remoting up and running. All told, the cmdlet will start the WinRM service, configure it to start automatically, register PowerShell as an endpoint, and even set up a Windows Firewall exception to permit incoming WinRM traffic.
Try it Now Go ahead and enable remoting on your second computer (or on the first one, if that’s the only one you have to work with). Make sure you’re running PowerShell as an administrator if you are on a Windows device (the Window’s title bar should read Administrator). If you’re not, close the shell, right-click the PowerShell icon in the Start menu, and select Run as Administrator from the context menu.
The most common error you will receive is “WinRM firewall exception will not work since one of the network connection types on this machine is set to Public.” Any network connection set to Public
can’t have Windows Firewall exceptions, so when Enable-PSRemoting
tries to create one, it fails. The only solution is to go into Windows and modify the network adapter setting so that whatever network you’re on is either Work or Home. But don’t do this if you’re connected to a public network (e.g., a public wireless hotspot), because you’ll be turning off some valuable security protections.
Note You don’t have to worry about PowerShell remoting and public networks as much on server operating systems, because they don’t have the same restrictions in the OS.
If you’re not excited about having to run around to every computer to enable remoting, don’t worry: you can also do it with a Group Policy Object (GPO). The necessary GPO settings are built into your domain controllers (you can download an ADM template from www.microsoft.com/en-us/download to add these GPO settings to an older domain’s domain controllers). Open a GPO and look under Computer Configuration > Administrative Templates > Windows Components. Near the bottom of the list, you’ll find both Remote Shell and Windows Remote Management. For now, we’ll assume you’ll run Enable-PSRemoting
on those computers that you want to configure, because at this point you’re probably playing around with only a virtual machine or two.
Note PowerShell’s about_remote_troubleshooting
help topic provides more coverage on using GPOs. Look for the “How to enable remoting in an enterprise” and “How to enable listeners by using a Group Policy” sections within that help topic.
PowerShell uses remoting in two distinct ways. The first is one-to-one, or 1:1, remoting. The second is one-to-many, or 1:N, remoting (and you’ll see it in the next section). With one-to-one remoting, you’re accessing a shell prompt on a single remote computer. Any commands you run will run directly on that computer, and you’ll see results in the shell window. This is vaguely similar to using SSH or Remote Desktop Connection, except you are limited to the command-line environment of Windows PowerShell. This kind of remoting also uses a fraction of the resources that Remote Desktop requires, so it imposes much less overhead on your servers.
Before we can connect to a remote computer, we need you to understand the difference between -hostname
and -computername
parameters:
PowerShell has no way of knowing what protocol you are trying to use, so you have to tell it. To establish a one-to-one connection with a remote computer, run the following command:
Enter-PSSession -HostName Ubuntu1 -UserName tylerl Enter-PSSession -ComputerName SRV2 -UserName contoso ylerl
Alternatively, you can use this syntax:
(You need to provide the correct computer name instead of SRV2
or Ubuntu1
.)
Assuming that you enabled remoting on your remote computer, and you’re all in the same domain, and your network is functioning correctly, you should get a connection established. PowerShell lets you know that you’ve succeeded by changing the shell prompt:
The shell prompt tells you that everything you’re doing is taking place on Ubunut1
(or whichever server you connected to). You can run whatever commands you like. You can even import modules.
Try it Now Try to create a remoting connection to your second computer or virtual machine. If you haven’t done so, you’ll also need to enable remoting on that computer before you try to connect to it. Note that you need to know the hostname or IP address.
Any command you run on the remote computer will run under the credentials you use to authenticate, so you’ll be able to do anything you’d normally have permission to do. It’s as if you logged into that computer’s console and used its copy of PowerShell directly.
Even if you have a PowerShell profile script on the remote computer, it won’t run when you connect using remoting. We haven’t fully covered profile scripts yet (they’re in chapter 26), but suffice it to say, they’re a batch of commands that run automatically each time you open the shell. Folks use them to automatically load shell extensions and modules and so forth. That doesn’t happen when you remote into a computer, so be aware of that.
Aside from this fairly minor caveat, you should be good to go. But wait—what do you do when you’re finished running commands on the remote computer? Many PowerShell cmdlets come in pairs, with one cmdlet doing something and the other doing the opposite. In this case, if Enter-PSSession
gets you into the remote computer, can you guess what would get you out of the remote computer? If you guessed Exit-PSSession
, give yourself a prize. The command doesn’t need any parameters; run it and your shell prompt will change back to normal, and the remote connection will close automatically.
Try it Now Exit the remoting session, if you created one. We’re done with it for now.
What if you forget to run Exit-PSSession
and instead close the PowerShell window? Don’t worry. PowerShell is smart enough to figure out what you did, and the remote connection will close all by itself.
We do have one caution to offer: When you’re remoting into a computer, don’t run Enter-PSSession
from that computer unless you fully understand what you’re doing. Let’s say you work on Computer A, which runs Ubuntu, and you remote into SRV2. Then, at the PowerShell prompt, you run this:
This causes Ubuntu1 to maintain an open connection to SRV2, which can start to create a remoting chain that’s hard to keep track of and that imposes unnecessary overhead on your servers. At times you may have to do this—we’re thinking mainly of instances where a computer such as SRV2 sits behind a firewall and you can’t access it directly, so you use SRV1 as a middleman to hop over to Server-DC4. But, as a general rule, try to avoid remote chaining. The PowerShell team has a great article on making a second hop in PowerShell Remoting at http://mng.bz/AxXe.
Caution Some people refer to remote chaining as the second hop, and it’s a major PowerShell gotcha. We offer a hint: If the PowerShell prompt is displaying a computer name, then you’re finished. You can’t issue any more remote control commands until you exit that session and “come back” to your computer.
When you’re using this one-to-one remoting, you don’t need to worry about objects being serialized and deserialized. As far as you’re concerned, you’re typing directly on the remote computer’s console. If you retrieve a process and pipe it to Stop-Process
, it’ll stop running, as you’d expect it to.
The next trick—and honestly, this is one of the coolest things in PowerShell—is to send a command to multiple remote computers at the same time. That’s right, full-scale distributed computing. Each computer will independently execute the command and send the results back to you. It’s all done with the Invoke-ScriptBlock
cmdlet, and it’s called one-to-many, or 1:N, remoting. The command looks like this:
Try it Now Run this command. Substitute the name of your remote computer (or computers) and username where we put our three server names.
Everything in those curly braces {}
gets transmitted to the remote computers—all three of them. By default, PowerShell talks to up to 32 computers at once; if you specify more than that, it will queue them up, and as one computer completes, the next one in line will begin. If you have an awesome network and powerful computers, you could raise that number by specifying the -throttleLimit
parameter of Invoke-ScriptBlock
. Read the command’s help for more information.
If you carefully read the help for Invoke-ScriptBlock
(see how we’re continuing to push those help files?), you’ll also notice a parameter that lets you specify a script file, rather than a command. That parameter lets you send an entire script from your local computer to the remote computers—meaning you can automate some complex tasks and have each computer do its own share of the work.
Try it Now Make sure you can identify the -ScriptBlock
parameter in the help for Invoke-ScriptBlock
and that you can spot the parameter that would enable you to specify a file path and name instead of a script block.
We want to circle back to the -HostName
parameter we mentioned at the beginning of the chapter. When we first used Invoke-ScriptBlock
, we typed a comma-separated list of hostnames, as we did in the previous example. But we work with a lot of computers, and we don’t want to have to type them all in every time. We keep text files for some of our common computer categories, such as web servers and domain controllers. Each text file contains one computer name per line, and that’s it—no commas, no quotes, no nothing. PowerShell makes it easy for us to use those files:
The parentheses here force PowerShell to execute Get-Content
first—the same way parentheses work in math. The results of Get-ScriptBlock
are then stuck into the -HostName
parameter, which works against each of the computers listed in the file.
We want to explain the differences between running commands by using Invoke-ScriptBlock
and running those same commands locally, as well as the differences between remoting and other forms of remote connectivity. For this discussion, we’ll use this command as our example:
Invoke-ScriptBlock -HostName SRV2,DC3,SRV4 -ScriptBlock { Get-Process pwsh -UserName tylerl | Where-Object {$_.Parent.ProcessName -like '*term*'}}
Another caveat to keep in mind about remoting is that the objects that come back to your computer aren’t fully functional. In most cases, they lack methods, because they’re no longer “attached” to “live” software.
For example, run this on your local computer, and you’ll notice that a System .Diagnostics.Process
object has numerous methods associated with it:
PS > Get-Process | Get-Member TypeName: System.Diagnostics.Process Name MemberType Definition ---- ---------- ---------- Handles AliasProperty Handles = Handlecount Name AliasProperty Name = ProcessName NPM AliasProperty NPM = NonpagedSystemMemory... PM AliasProperty PM = PagedMemorySize64 SI AliasProperty SI = SessionId VM AliasProperty VM = VirtualMemorySize64 WS AliasProperty WS = WorkingSet64 Parent CodeProperty System.Object Parent{get=G... Disposed Event System.EventHandler Dispos... ErrorDataReceived Event System.Diagnostics.DataRec... Exited Event System.EventHandler Exited... OutputDataReceived Event System.Diagnostics.DataRec... BeginErrorReadLine Method void BeginErrorReadLine() BeginOutputReadLine Method void BeginOutputReadLine() CancelErrorRead Method void CancelErrorRead() CancelOutputRead Method void CancelOutputRead() Close Method void Close() CloseMainWindow Method bool CloseMainWindow() Dispose Method void Dispose(), void IDisp... Equals Method bool Equals(System.Object ... GetHashCode Method int GetHashCode() GetLifetimeService Method System.Object GetLifetimeS... GetType Method type GetType() InitializeLifetimeService Method System.Object InitializeLi... Kill Method void Kill(), void Kill(boo... Refresh Method void Refresh() Start Method bool Start() ToString Method string ToString() WaitForExit Method void WaitForExit(), bool W... WaitForInputIdle Method bool WaitForInputIdle(), b... __NounName NoteProperty string __NounName=Process
Now get some of those same objects via remoting:
PS > Invoke-ScriptBlock {Get-Process} -HostName localhost -UserName tylerl | ➥ Get-Member TypeName: Deserialized.System.Diagnostics.Process Name MemberType Definition ---- ---------- ---------- GetType Method type GetType() ToString Method string ToString(), string To... Company NoteProperty object Company=null CPU NoteProperty object CPU=null Description NoteProperty object Description=null FileVersion NoteProperty object FileVersion=null Handles NoteProperty int Handles=0 Name NoteProperty string Name= NPM NoteProperty long NPM=0 Parent NoteProperty object Parent=null Path NoteProperty object Path=null PM NoteProperty long PM=0 Product NoteProperty object Product=null ProductVersion NoteProperty object ProductVersion=null PSComputerName NoteProperty string PSComputerName=localh... PSShowComputerName NoteProperty bool PSShowComputerName=True RunspaceId NoteProperty guid RunspaceId=26297051-1cb... SI NoteProperty int SI=53860 VM NoteProperty long VM=0 WS NoteProperty long WS=0 __NounName NoteProperty string __NounName=Process BasePriority Property System.Int32 {get;set;} Container Property {get;set;} EnableRaisingEvents Property System.Boolean {get;set;}
The methods—except the universal ToString
()
and GetType()
methods common to all objects—are gone. This is a read-only copy of the object; you can’t tell it to do things like stop, pause, resume, and so forth. So any actions you want taken as the result of your command should be included in the script block that’s sent to the remote computer; that way, the objects are still live and contain all of their methods.
We’ll cite our original example again:
Invoke-ScriptBlock -HostName SRV2,DC3,SRV4 -ScriptBlock { Get-Process pwsh -UserName tylerl | Where-Object {$_.Parent.ProcessName -like '*term*'}}
The computers are contacted in parallel, meaning the command can complete somewhat more quickly.
Each computer queries the records and filters them locally. The only data transmitted across the network is the result of that filtering, meaning that only the records we care about are transmitted.
Before transmitting, each computer serializes its output into XML. Our computer receives that XML and deserializes it back into something that looks like objects. But they aren’t real event log objects, and that might limit what we can do with them once they’re on our computer.
Now, compare it to this alternative:
Invoke-ScriptBlock -HostName SRV2,DC3,SRV4 -ScriptBlock { Get-Process pwsh } -UserName tylerl | Where-Object {$_.Parent.ProcessName -like '*term*'}
The differences are subtle. Well, we see only one difference: we moved one of those curly braces.
In the second version, only Get-Process
is being invoked remotely. All of the results generated by Get-Process
are serialized and sent to our computer, where they’re deserialized into objects and then piped to Where
and filtered. The second version of the command is less efficient, because a lot of unnecessary data is being transmitted across the network, and our one computer has to filter the results from three computers, rather than those three computers filtering their own results for us. The second version, then, is a bad idea.
Let’s look at two versions of another command, starting with the following:
Invoke-ScriptBlock -ComputerName SRV2 -ScriptBlock { Get-Process -name pwsh } -UserName tylerl | Stop-Process
Now let’s look at the second version:
Invoke-ScriptBlock -ComputerName SRV2 -ScriptBlock { Get-Process -name pwsh } -UserName tylerl | Stop-Process }
Once again, the only difference between these two is the placement of a curly brace. But in this example, the first version of the command won’t work.
Look carefully: we’re sending Get-Process
-name
pwsh
to the remote computer. The remote computer retrieves the specified process, serializes it into XML, and sends it to us across the network. Our computer receives that XML, deserializes it back into an object, and pipes it to Stop-Process
. The problem is that the deserialized XML doesn’t contain enough information for our computer to realize that the process came from a remote machine. Instead, our computer will try to stop the pwsh
process running locally, which isn’t what we want at all.
The moral of the story is to always complete as much of your processing on the remote computer as possible. The only thing you should expect to do with the results of Invoke-ScriptBlock
is to display them or store them as a report, or a data file, and so forth. The second version of our command follows that advice: what’s being sent to the remote computer is Get-Process
-name
pwsh
|
Stop-Process
, so the entire command—both getting the process and stopping it—happens on the remote computer. Because Stop-Process
doesn’t normally produce any output, there won’t be any objects to serialize and send to us, so we won’t see anything on our local console. But the command will do what we want: stop the pwsh
process on the remote computer, not on our local machine.
Whenever we use Invoke-ScriptBlock
, we always look at the commands after it. If we see commands for formatting, or for exporting data, we’re fine, because it’s okay to do those things with the results of Invoke-ScriptBlock
. But if Invoke-ScriptBlock
is followed by action cmdlets—ones that start, stop, set, change, or do something else—then we sit back and try to think about what we’re doing. Ideally, we want all of those actions to happen on the remote computer, not on our local computer.
The previous examples have all used ad hoc remoting connections, meaning that we specified hostnames. If you’re going to be reconnecting to the same computer (or computers) several times within a short period of time, you can create reusable, persistent connections to use instead. We cover that technique in chapter 18.
We should also acknowledge that not every company is going to allow PowerShell remoting to be enabled—at least, not right away. Companies with extremely restrictive security policies may, for example, have firewalls on all client and server computers, which would block the remoting connection. If your company is one of those, see whether an exception is in place for SSH or WinRM. We find that’s a common exception, because administrators obviously need some remote connectivity to servers. If SSH or WinRM is allowed, then you can user PowerShell remoting over SSH.
Whenever beginners using remoting, some common problems crop up over the course of the day:
Remoting is designed to be more or less automatically configured. If every computer involved is on the same domain, and your username is the same, things will typically work great. If not, you need to run help about_remote_troubleshooting
and dig into the details.
When you invoke a command, you’re asking the remote computer to launch PowerShell, run your command, and then close PowerShell. The next command you invoke on that same remote computer will be starting from scratch—anything that was run in the first invocation will no longer be in effect. If you need to run a whole series of related commands, put them all into the same invocation.
Note For this lab, you need a computer running PowerShell v7 or later. Ideally, you should have two computers on the same network with remoting enabled.
It’s time to combine some of what you’ve learned about remoting with what you’ve learned in previous chapters. See if you can accomplish the following tasks:
Make a one-to-one connection with a remote computer (or with localhost
if you have only one computer). Launch your favorite text editor. What happens?
Using Invoke-ScriptBlock
, retrieve a list of processes currently running from one or two remote computers (it’s okay to use localhost
twice if you have only one computer). Format the results as a wide list. (Hint: It’s okay to retrieve results and have the formatting occur on your computer—don’t include the Format-
cmdlets in the commands that are invoked remotely.)
Use Invoke-ScriptBlock
to get a list of the top 10 processes for virtual memory (VM) usage. Target one or two remote computers, if you can; if you have only one computer, target localhost
twice.
Create a text file that contains three computer names, with one name per line. It’s okay to use the same computer name, or localhost
, three times if you have access to only one computer. Then use Invoke-ScriptBlock
to retrieve the 10 newest files from the home directory (~
).
Using Invoke-ScriptBlock
, query one or more remote computers to display the property PSVersion
from the $PSVersionTable
variable. (Hint: This requires you to get the property of an item.)
The nano process will launch, but there won’t be any interactive process either locally or remotely. In fact, run this way, the prompt won’t return until the nano process ends—although an alternative command to launch it is Start-Process nano
.
[SRV2] PS C:UsersAdministratorDocuments> Notepad
The Notepad process will launch, but there won’t be any interactive process either locally or remotely. In fact, run this way, the prompt won’t return until the Notepad process ends—although an alternative command to launch it is Start-Process Notepad
.
Invoke-ScriptBlock –scriptblock {Get-Process } -HostName
➥ Server01,Server02 -UserName yourUser | Format-Wide -Column 4
Invoke-ScriptBlock -scriptblock {get-process | sort VM -Descending |
➥ Select-first 10} –HostName Server01,Server02 -UserN
Invoke-ScriptBlock -scriptblock { Get-ChildItem ~/* | Sort-Object
➥ -Property LastWriteTime -Descending | Select-Object -First 10}
Invoke-ScriptBlock –scriptblock $ -Server01,Server02 -UserName yourUser
We could cover a lot more about remoting in PowerShell—enough that you’d be reading about it for another month of lunches. Unfortunately, some of its trickier bits aren’t well documented. We suggest heading up to PowerShell.org, and more specifically to their e-book resources, where Don and fellow MVP Dr. Tobias Weltner have put together a comprehensive (and free!) Secrets of PowerShell Remoting mini e-book for you (see https://leanpub.com/secretsofpowershellremoting). The guide rehashes some of the basics you learned in this chapter, but it primarily focuses on detailed, step-by-step directions (with color screenshots) that show how to configure a variety of remoting scenarios. The guide also digs into some of the grittier details of the protocol and troubleshooting, and even has a short section on how to talk to information security people about remoting. The guide is updated periodically, so check back every few months to make sure you have the latest edition.
18.118.147.160