Hello tech world this is TechThoughts
and welcome to this special tech thoughts video series focused on learning
PowerShell. This is an operationally designed series that aims to get you
ramped up and using PowerShell quickly. This is episode nine in the series,
PowerShell remoting. As always if you prefer written documentation the
corresponding article for this topic can be found on the techthoughts.info blog
which i've linked in the description below. Let's go ahead and get started. In
the Learn Powershell series so far we've learned how powerful PowerShell can be
when managing just a local device. But now we're gonna expand on that
capability and learn how to manage hundreds or even thousands of servers
using PowerShell. This episode is a little bit different than previous
episodes in that it assumes some general systems knowledge outside of PowerShell.
We're going to be establishing a connection between two devices, and so a
general understanding of network protocols, firewalls, routers, and general
server management is required in order to be able to troubleshoot and
understand how to get a connection from point A to point B. And all of that
occurs outside of general PowerShell. Once we establish that connection we're
also going to have to be able to authenticate to that end device. So an
understanding of authentication protocols is also required. So things
like Kerberos, NTLM, basic authentication, negotiation, and CredSSP are helpful in understanding how some of this operates behind the scenes.
When you're done with this episode you're going to have a pretty solid
understanding of how to touch every device inside of your environment. So, you
should be at an experience level where you have some grasp on these networking
and authentication concepts. To further complicate matters there are many
possible connection scenarios. Take a look at this graphic. Every single one of
these is gonna require a slightly different configuration. This video can't
cover every single one of those. So you are likely going to have to do some
additional research on this topic depending on the setup of your
environment. Don't feel put off by the complexity of this topic. If you're
wondering why you should invest time or resources into learning how to implement
PowerShell remoting inside of your environment
remember that PowerShell remoting is one of the most powerful capabilities
that PowerShell has to offer. This is the component that turns a three-week task
into a five-minute task. If you get a ticket that would normally take you say
half an hour to accomplish on various devices inside of your environment. This
is the capability that turns that into a five-minute task. So this is definitely
something that's worth investing in. Let's dive into the code with Windows
PowerShell remoting first. We are going to be covering quite a bit of code in this episode and it's code that you're likely going to want to refer back to
later. Keep in mind that this series not only has a corresponding blog article,
but it also has a corresponding GitHub. So I'll make sure to include a link to
this in the description below but you can come on to the GitHub for the series
click on the learn PowerShell folder and find every single episode and the code
that was demoed in each of these. So if you click on episode 9 you'll find all
of the code for easy reference that we're going to be demoing today. Okay so
winrm is the protocol that PowerShell uses for establishing remote connections
inside of Windows. And what you need to understand about winrm is it's not
something that's natively set up by default inside of Windows. So you don't
just get this in your environment you need to configure it to listen for winrm calls. winrm comes in two pieces a client and as a service I'll be showing
you that in just a moment. So the client is used to establish outbound calls and
the service is what's going to be listening for inbound calls. So we can
use this cmdlet, Test-WSMan to see if this device is configured for winrm.
so I'll go ahead and click f8 and if you get this back that means that the device
is configured for winrm access. If we hop over to a different device and run
the same command if you give back this error that's an indication that winrm
has not been configured and set up on this particular device. To get winrm
setup the easiest thing to do is just to run winrm quickconfig. And this will
set up winrm the client and the service with all the default settings. There are
many different winrm settings that you can configure. I'll be briefly touching
on a couple of those but you can still use the quick config to do things like
configure whether you want to use HTTP or HTTPS for your remote connections.
This will start to make a little bit more sense when we look in the actual
winrm settings. We can do that using the winrm command winrm get and then we
can look at the client and we can also look at the service let's start with the
client. I'll go ahead and run F8 on this line. And if we take a look at this so
what this is telling us is that this client is able to use the following
authentication protocols. And it's configured to use the default ports when
connecting outbound so to other devices so this will use 5985
for HTTP traffic and 5986 for HTTPS traffic. And the trusted
host currently loaded into this is just one. Okay so if you're wondering why you
would ever use HTTP over 5985 keep in mind that for domain to
domain traffic so like a Windows Device joined to a domain and this other remote
device here that I have that's also joined to the same domain, that that's
supposed to be within the confines of your trusted network. And that means that
you shouldn't be going out over the Internet's all contained within side of
your own enterprise network. So by default especially within the same
domain winrm is going to default to 5985. Again depending on the various configuration scenarios you will
likely find that you have to jump out to HTTPS instead. But after running winrm
quickconfig this is very typical for what you're going to be seeing set up
for your clients. Let's go ahead and look at the service now and this is the error
that you'll get when you're not running as an administrator. So I'm gonna go
ahead and copy this out real quick I'm going to close VSCode and I'm gonna
relaunch it as administrator. You can shift right click and run as
administrator. Okay and I'll go ahead and run that winrm service command. Notice
we get a little bit more information because this is what's actually
listening for inbound communications. So we can see things like this is not
accepting every single authentication protocol. In the current configuration
this is only accepting Kerberos and negotiate. It is configured to use the
default ports of 5985 and 5986. We are
currently allowing remote access to this device, and again all of this is
configurable using the winrm commands to configure every single one of these
settings depending on the needs of your
individual environment. Now let's go ahead and take a look at the listener
and the listener is the thing that's actually actively listening for winrm
connections. So I'm gonna run the command winrm enumerate in the winrm config
listener again you don't have to memorize these they're available for
easy access on the GitHub. So what this is telling us is that winrm is
currently listening on these IP addresses. So if your server or device
has multiple NICs or multiple IPs you can configure which of those IPs are
going to be responding to winrm calls. This is currently configured for HTTP
only and it will listen in on any address inbound. So again this is can be
very granular and very secured so you can tell winrm that it's only able to
accept remote connections from certain addresses over certain protocols using
certain authentication mechanisms. So its a very powerful and highly secure way
that you can manage your environment. OK so let's go ahead and introduce our two
devices that I'm going to be using today for demonstrating Windows remote access. On the right here we have a remote device called MDT which is joined to the
ark domain. And on this side I have will use our environment variable computer
name. This is HUB. And if we look at in the
environment variable of user domain this is also on the ark domain. So both of
these devices are on ark and by default that means they're going to be using
winrm HTTP because this is a trusted network on this domain. This is a very
common remote access scenario for your enterprise environment. Ok so let's go
ahead and remotely verify if this device MDT
is configured and accepting winrm commands from this device over here. We
can continue to use the Test-WSMan cmdlet to do that. Before we get started
on that let's go ahead and learn how to use the Get-Credential cmdlet.
Notice that I'm loading the results of Get-Credential into the credential
variable. I'll go ahead and run f8 and notice that immediately prompts me to
enter the credentials that are going to have access to this remote device. Since
these are on the same domain I'm going to go ahead and enter
my domain credentials that have access to the MDT server. So notice if I pound
out credential in the console down here that credential contains the username
and password. But I can drill into the sub property of username and see that,
but notice that if I drill into the sub property of password that I'm unable to
see that. It is stored securely. So this is a nice safe way to store your
credentials and send them over the wire. So now I use Test-WSMan to establish a
connection to MDT, negotiate what type of authentication should be utilized in
this transaction, and I'll use the credentials that we just specified to
establish that connection. So I'll go ahead and click f8 and notice that we
get the same return as when we're testing locally indicating that our
credentials are good, our authentication method is good, and that MDT is
configured for winrm and accepting connections. So just a quick way to
verify if your remote devices are configured for winrm.
Here's another useful cmdlet for verifying that you are actively
listening on 5985 which is the default winrm port on Winows.
So you can run the Get-NetTCPConnection cmdlet and specify that
5985. Remember depending on which version of PowerShell that
you're running that not all cmdlets are available versus 6 versus 5.1.
Definitely check out my video on PowerShell history on why that is
operating that way. So I'll go ahead and copy this cmdlet, hop over to
PowerShell 5.1 and run. And we can see that we are listening on 5985 on this particular device. You can also use Test-NetConnection to see if a
remote device is also listening and responding on port 5985.
So these are just some helpful cmdlets so you can see if the
network is configured both locally and remotely to accept winrm traffic. Okay
now we've got some of those basic configurations out of the way let's have
some fun getting set up for establishing a remote connection to this device and
doing things on that remote server. So again we've already established the
credential and loaded it in here and that variable is still available in our
current PowerShel session. So now we'll use the Enter-PSSession
and what this is going to do in if you're familiar with SSH at all in the
Linux world this is very similar to that. So we're going to enter a PowerShell
session on the remote device so I'll change this example to MDT, and we're
going to drop into a PowerShell session on the MDT server. Let me show
you what that looks like. So notice if I type in hostname down here that we are
currently on HUB. But if I enter this PS session on MDT and I click F8, notice
that we get this front-loaded MDT indicating that we're no longer on HUB.
We are actually running commands now in the context of the remote MDT server. So
you'll notice that if I type in hostname now, that the return is MDT because it
ran on that remote device. This is a fantastic way to replace RDP in your
Windows environment. You don't need to RDP to a server anymore
you can do everything as you need to do from this console now. So if you want to
check the service of bits on that remote device you can see that MDT currently
has that service stopped. And any other management that you need to do from a
PowerShell perspective can now be executed and run under the context of
MDT. When you're ready to drop back to your local device simply type exit and
notice that we're now back on our normal PowerShell session, and if I type in
hostname again we're back on HUB. So Enter-PSSession is a fantastic way to
manage a remote device but it is only capable of managing one device at a time.
So you are inside of that session on the remote device and only for that remote
server that you've specified. So this is a great way to manage a remote device
but we can use winrm to influence a great many servers, not just one at a
time. And in order to do that we're going to have to start establishing sessions.
So this is where we're going to start to get into the New-PSSession. So a new
PowerShell session cmdlet. So let's walk through this real quickly.
We're going to be running this New-PSSession cmdlet specifying the
computer name that we want access to. And of course the credentials that have
access to that remote device. So again we're going to be specifying MDT as our
remote device and using the credential variable that we've
already loaded using Get-Credential. So I'm gonna go ahead and run F,8 and notice that nothing seems to have really have happened so let's look at this session
variable. What this is saying is that this is now loaded with an open and
active connection to that remote machine. So we can leverage this session for a
wide variety of different cmdlets. It's kind of an open gateway to that
device now. So let me kind of show you what that might look like. We'll come
down here to our Invoke-Command because Invoke-Command is the way that we're
going to be leveraging these sessions to perform different various tasks. So I
will use the Invoke-Command, I will specify the session parameter, provide
the session variable that we just created which is an open active
connection to that remote machine and I'll go ahead and specify the script
block parameter down here and I will open and close some curly braces. And we
can put things in here like hostname. Lets track what this is going to
accomplish. We're gonna invoke a command against the session that we just
previously established, and it's gonna run the script hostname. So what do you
expect to be returned by this? Let's go ahead and click enter and find out. It
returned MDT. So we just ran a command against a session and it returned the
host name which is the script that we specified for it to run. Let's come back
up to these session variables and notice that we can create sessions to multiple
devices. So we can do things like specify a list of servers. You could even specify
using Get-Content an entire list of hundreds of devices. So that would load
an entire list into the devices variable and then you could establish a multi
session to multiple different devices inside of that list using the same
credentials. So I will alter this example to include not only MDT but will
include another device as well. So I'll go ahead and do MDT and I have a another
computer in this environment called DC. So we already have our credentials
loaded, we'll establish a multi session, so a New-PSSession to both of these
computer names. I'll go ahead and click F8. Notice if we pound out the
multi-session variable down here that this now has two active and established
remote connections to this machine. We can push the up arrow on our keyboard a
couple times, come back to this Invoke-Command, and this time we'll change this
session to multi session. So I'll come over here and change this to multi
session and tab for auto completion. And again we're just going to run hostname
against both of those devices. Go ahead and click enter. And we just ran that
hostname request against two devices very quickly very easily utilizing some
basic PowerShell to establish those PS sessions to those remote devices. I hope
you're starting to see the power behind this capability. Now again there are some
advanced features in here and I've included some examples for you to
reference depending on what you have in your environment. Which you can
establish things over SSL. Once you start using SSL for winrm you are gonna have
a start managing certificates. You may need the ability to skip a check for
authority, or some type of certificate revocation is going to be skipped so
there's options in here for your PowerShell sessions on all kinds of
different factors that you might encounter inside of your environment. So
definitely come back here reference some of these advanced examples. One thing to
note is that when you are establishing connections over IP versus hostname in a
domain environment you are gonna have to fall back to SSL so that's something to
keep in mind. All right so now let's take a look at some of the more advanced
Invoke-Command examples to start getting a sense of how powerful this capability
really is. I'm going to change this session to the multi session that we had
a second ago which is still active and open. So if we check down here we still
have open and active sessions to those machines. I'm gonna change this session
variable in this Invoke-Command to multi session and the script block that we're
gonna be running this time is a Get-CIMInstance and we're gonna be finding the
number of logical processors that that remote device has. So this is a quick way
to check how many CPUs the remote device has. So again we're running the Invoke-Command against those sessions previously established, and running
the following command in our script block. So I'll go ahead and click f8 and
now I just audited my environment and we can see that the first one has three, and
the first one has two. Now this is what I want to caution you about when you're
running commands remotely in this fashion. Which device is which? Well they
don't run in order. What happened is Invoke-Command runs in parallel. And, what it's getting back is the first machine to respond. So this is something you
definitely have to keep in mind when you're running Invoke-Command against
multiple sessions using winrm. So this is representative of a device that
responded first not necessarily the device that you had first in the order
inside of your list. So it will come back in an out-of-order fashion depending on
which device is the fastest. And so you'll need to take additional steps to
identify the devices returned, so you might want to include the computer name
inside of your script block or something to that effect so that you can see which
device has actually responded. I've included a couple more examples here of
checking the RAM on the remote device and checking the free space on the C
Drive, but the sky's the limit. If you can
imagine it and write some PowerShell code to do it, you can have that code
execute against an unlimited number of devices very rapidly inside of your
environment. So try to imagine a ticket coming into
your queue, or some type of task coming down from leadership where you have to stop
the bits service on every single device inside of your environment. I mean
normally that would be a pretty huge undertaking if you were to start RDP'ing to those devices inside of your environment. You might have to get with
the active directory team to establish some type of group policy to start
pushing that out, or you could you know get with your change management team and with one line you could stop all the bits service inside of your environment. So
how would you go about that? Well it's the same thing you can just copy this
bring it up here invoke that command against the multi session and you would
simply stop service named bits. And this would stop bits
service on every single remote device that's loaded inside of the sessions
variable. Let's go ahead and hop over to Linux now. Notice I've got two Ubuntu
machines here and instead of winrm Linux is going to be using SSH to
establish remote connections inside of PowerShell. That means you will need to
have SSH setup on the device and you will need to have it configured to allow
PowerShell to engage SSH. So this is going to vary a little bit between
distros but at a high level you're just gonna be installing SSH and configuring
it for PowerShell. I've linked a couple examples in the techthoughts.info blog and
you can search around online to find out how to configure PowerShell for your
individual distro. So we'll install the open SSH client inside of Ubuntu. I've
gone ahead and already done that which you can run the following command and
we'll also do that for the OpenSSH server to get that installed. Once you've
got that set up you will need to go ahead and edit your sshd config file
with a couple of settings specific for PowerShell. So we'll go ahead and open up
the following location for edit which is etc/ssh/sshd_config we will
need to make sure that password authentication is set to yes. So make
sure that that is set that way. And we'll also need to go ahead and add PowerShell
as a sub system. So make sure the following is also included in your
config. If you don't feel like typing all that out go ahead and reference the
GitHub. You can go ahead and quickly copy that into your config file. And once
we've got that saved and inside of your config you can go ahead and restart the
SSH service. Once you've got past this initial configuration for SSH inside of
PowerShell you can go ahead and essentially run the same commands that
we were running previously except with one caveat of specifying the ssh
transport. So we'll go ahead and establish the session using New-PSSession. We'll specify our hostname. Lets go ahead and check what our remote host name is. So we'll go ahead and punch that in. We'll specify our
username that has accessibility to that remote device, and will specify the ssh
transport parameter. So let me highlight this so you can see a little bit better.
We're establishing the session variable, New-PSSession to our remote host name,
specifying our username, and using the ssh transport. So i'll go ahead and click
enter. That's gonna prompt me for a password to the remote device and I now
have if I pound out session a remote open session to this remote Ubuntu
device over SSH, very similar to what we just accomplished in Windows a moment
ago. I can of course use Invoke-Command against that remote device. Specify our
session in our session variable and our script block open and close braces and
we can run Get-Process. Ah, the mistake I made here is that you do not need to
specify the computer name because that is already included inside of our
session variable. So I'm going to back out that computer name and include just
our session variable and execute that and this is returning the processes from
that remote device. Notice that we get the return from that remote device name
whereas I am currently on this particular device. So pretty
straightforward. Same commands slightly different use of the ssh transport
parameter but you can establish remote connections using PowerShell over ssh
between linux devices. One question you may be wondering is can you do Linux to
Windows, and Windows to Linux? The answer is yes! That is a little bit outside the
scope of this particular episode but you can definitely search around and
find some advanced configuration techniques for making that a possibility.
I would expect over the coming months and years for that to be come a lot more
seamless but today it requires a little bit of tweaking in order to get remote
connections from Linux to Windows, and Windows to Linux. But by the time you're
watching this episode that may have become a more easy task to accomplish.
Let's hop back for really quickly and take a look at some more advanced
configuration techniques. And I'm gonna go through these kind of
quickly because again this is just an introductory episode into remote
capabilities in PowerShell, but there is the concept of trusted hosts. Especially
when you're dealing with devices that are outside of your domain and you may
only have local credentials to you'll often see the need to add the server
name as a trusted host. So you may need to specify a device name and add that in
to winrm as a trusted end device. So I've included some examples on how to
accomplish that so in your lab at home or with a couple of devices that you
have in your home network you may need to add those device names in order to
connect to them. Again by default most of your devices are going to establish winrm connections over HTTP which is an example that we shown earlier. Whereas if
you start testing devices outside of your domain or start using IP addresses
you're going to need to start connecting to those using HTTPS, which is gonna
require you to configure your winrm listener to use HTTPS, and specifying
certificates and thumb prints for those winrm connections. I've included
guidelines on how to setup that inside of the techthoughts.info blog so you'll find
some additional reading links to get started if you need to use SSL for winrm. And again here's an example of using winrm to connect to a remote device
over IP which is gonna require the use of SSL. And a couple of other advanced
techniques of changing the default port if you don't want to use the default winrm ports, and as well as some native cmdletsfor checking winrm settings
Get-WSManInstance if you don't want to use the winrm commands themselves.
Again all that's available for reference for easy access on the GitHub which I've
linked in the description below. I know this episode has covered a lot of ground
and requires a lot of external knowledge outside of PowerShell, but I want to
leave you with this final example to kind of really drive home how powerful
this capability really is. This is gonna be our most complicated final example to
date in the series but we are nine episodes into the series now so we're
going to start introducing some more advanced concepts.
At a high level what we're going to be accomplishing is establishing a list of
servers and remotely connecting to all of them to perform an audit about some
basic information very quickly. Lets walk through this and see how it
operates. The first thing we're going to do is load some servers into this
servers variable. How you do that is entirely up to you. You can specify the
names provide a list what I'm going to elect to do is pull every single server
that's inside of my domain. So I'm gonna run Get-ADComputer and I'm going to
filter star. So I'm gonna pull in every single device that's inside of that and
the only thing I'm interested in from those AD object returns is the name, so
I'm going to go ahead and wrap that in parentheses and just pull out the name
and load that into servers. So I'm gonna go ahead and click F8, and now you'll
notice that if I pipe that to measure I have 24 servers in my domain that are
loaded inside of that. So we'll be reaching out to 24 devices to audit them.
The next thing up is to specify some credentials that have access to those
particular devices. I'll go ahead and run F8 and load that into the credentials
variable. So I'll go ahead and specify my creds here. Next up is to create an array.
We need to store our results inside of this array so that's going to be at open
close parenthesis for a nice blank array. I'll go ahead and click F8. Now this is a
new topic for us that I'm introducing in this final example which is splatting.
It's a very cool concept and what we're doing here is we're pre determining the
parameters. So let me explain what that's actually doing. The syntax for this is @
and then the open curly Q brace and close curly Q brace and on the left side
here what you're seeing is the parameters and then the values of those
parameters on the right side. Don't try to over complicate this this
is the exact same thing as if I came down here in an Invoke-Command and ran
ComputerName here and specified the computer names directly here. Rather than
specifying the ComputerName parameter, the credential parameter, or the error
variable parameter and the ErrorAction parameter all inside of this line one
at a time, what I'm instead doing is specifying those parameters in a
predetermined fashion into the invoke splat. And so all of these parameters are
predetermined and then I'm splatting those parameters utilizing this special
@ here and so all of those are predetermined and are going to actually
be inside of here, inside of that splat invoke splat. So let's talk about some of
the parameters that we're specifying. We're going to be touching every single
server that I just pulled in from the domain. We're gonna be using the creds
that I just specified here. I'm going to do any errors that are encountered and
send those to a custom error variable. So if you've watched my error episode on
PowerShell you'll know that by default that will go out to the Error variable
pipeline, but I'm gonna send this to a specific error so we can capture any
errors that are encountered in our remote command run into the connectErrors variable. And then any action, any error that we encounter I just want it
to silently continue. So what does that mean? Well that means that as we loop
through in parallel using Invoke-Command against all of these different servers
that we're pulling from the domain. I don't want to see any errors in red on
the screen as we loop through those. I just want to silently continue and try
to connect to every single device on my domain. Now remember in your environment there's a wide variety of reasons that a device might not respond. It could be
down for maintenance, or it could not be configured for winrm. So we're gonna
capture those and put them out to the error variable and then silently
continue and try to reach every device for our audit that we're trying to
accomplish. So we're using those parameters in the Invoke-Command with
our splat, and the script block that we're gonna be running is pretty involved. So
every single thing that's included in between this orange curly brace, and this
orange curly brace is the PowerShell logic that is going to be run against
our remote device. So I could take all this away to reduce the complexity and
really what we're doing is running commands inside of this script block
against all those remote devices using the credentials that we specified.
I'll go ahead and return that back in, and let's just briefly cover the logic
behind here. I'm going to declare a custom object because we're gonna be
running some code here inside of this that is not native cmdlets.
And so what do I mean by that? Well I want to capture multiple different
pieces of information in this audit. I want to capture the computer name, I want to capture the number of CPUs, memory, and free space. Well there's not a cmdlet that returns those four things natively. And so I'm declaring up custom
PowerShell objects that we're going to be setting up to actually capture those
individual pieces of information from various different cmdlets. So
notice that I'm loading all of that into the object variable. So now $object will
have the capacity to store the name of the computer, the number of CPUs, the
amount of memory, and the amount of free space on the hard drive. So this may seem
complicated to you but let's walk through how easy this is. So this object
variable the CPU parameter I'm going to store the results using Get-CIMInstance. So you can see this as the CPU results for this $object that we've
created up here is going to be whatever is returned from this PowerShell logic here.
The same for this the object memory is going to be running some logic using
Get-CIMInstance to evaluate the memory of the box, doing some math to
round out the bytes to actual gigabytes so on and so forth. And then again our
drive data we're going to be loading some common logic for getting the PS
Drive, selecting how much is used versus free, and just performing some
calculations using simple math on how to calculate how much free space is left on
the drive. Once we have that information we're gonna load that into the object
free space and return that object back to our management device. This may seem a little complex to you but once we execute it I think you'll start to see
it all come together. Again, in this episode it's not so much important to
understand how we're achieving the actual audit logic. it's more important to see how we can send a piece of code out to as many
devices as we want and have them gather information or perform tasks for us. So
that's our Invoke-Command here which is going to store the results and the
remote results. And then we're going to take that connectErrors variable and
remember our connect errors variable is where we're sending any error that we
encounter out to that particular variable. And we're gonna loop through
that basically using Where-Object and Select-Object and determine hey, did you
have any problems connecting to any of those devices? Again this may seem a
little confusing about what it's accomplishing to you but once you see it
in action I think it'll start coming together. I'm
gonna load all this code the error code and the execution code inside of our
window here. So I'm gonna highlight all of this and I'm gonna run the selection
again you can use F8 to do that. So this is running that code against every
single device that we gather from the domain. So auditing for CPU, hostname, how much free space is in the drive, how much memory every single one of those devices
has. So let's just take just a moment to run in parallel against every single
device that we gathered in. Okay so just in a few moments that's already
completed, and because we loaded the remote results into the remote results
variable, all of my successes should be in there. And we loaded this variable
remote failures with evaluation of that connect errors variable with some
criteria. Let's explore what our end results were. So I will look at my remote
results first and unsurprisingly we see the exact same custom object that we
specified. So notice that our custom object was named CPUs, memory, and free
space. And we see that exact same return here with a little bit of additional
information from the remote call which is always appended when running Invoke-Command. So we see our name, CPUs, and free space against DC, MDT, and another device called RDPG. So we can see here very quickly and
easily the RDPG has two CPUs, one gig of memory, and 64 percent free space
remaining on the hard drive. And we got this information in literally seconds
against every device inside of our environment. Well now let's go down to
remote failures and we now see here that these following devices it was unable to
connect to you for a variety of different reasons. But what we have at
the end of this audit is those devices that we need to go explore and adjust.
Maybe they don't have winrm set up and we have a list of devices that were
successfully audited. So this is a great and easy way to shotgun out a quick
question to your environment to ask it any question that you need answered for
your team or your management. And again if you had run something that made a
change against your environment definitely go through those proper
change controls but you could definitely make some very quick and easy changes to your environment using this methodology as well. Again this is one of the more
complicated topics inside of PowerShell, but it's one of the most empowering.
Definitely get a handle around this! Ask questions inside of the comments section
below. If I can help you out I'll do my best to do so. If you found this video
helpful go ahead and click that like button, and subscribe for more tech
thoughts videos.