1. Changing the local administrator password with PowerShell
Let’s assume you’re logged in as a domain administrator on a Windows 7
desktop that belongs to your domain. Now, let’s say you want to change
the local admin password on a remote server in Chicago named
CHI-WIN7-22.
After an account password is used for some time, the chances of it
getting exposed gets higher. That’s why you need to change your
passwords from time to time.
The first thing to do to change the admin password in question is to
create an ADSI object for the local administrator on that computer. That
can be achieved by typing this in your PowerShell screen:
[ADSI]$Admin=”WinNT://CHI-WIN7-22/Administrator”
This will essentially retrieve the admin account on
CHI-WIN7-22 and assign it to an ADSI object named $
Admin.
The WinNT monicker in that string is case-sensitive and is a common
source of error, so take note of that. If you want to connect to another
computer, just replace
CHI-WIN7-22 with the name of the computer you want to connect to.
Naturally, you’ll want to know first how long the password has been
in use to determine whether or not the time has come to change it. You
can obtain that information from $
Admin by typing in:
$Admin.PasswordAge
That will display the time elapsed since the password of that account
was last changed. However, since the resulting value is expressed in
seconds, I normally divide it by 86,400, which is the number of seconds
in a day:
$Admin.PasswordAge.Value/86400
The result will then be the same time elapsed but expressed in days,
which I find more meaningful. If you notice, we used the Value property
here. That’s because the
PasswordAge is actually stored
as a collection, and so we need the value of that collection in order
to return a number that we can perform a division operation on.
Finally, you can change the password by invoking the
SetPassword method and then using the new password as the argument. For example, if you want the new password to be
S3cre+WOrd, then type:
$Admin.SetPassword(“S3cre+WOrd”)
Note: After you hit enter, don’t expect any confirmation message
because there won’t be any. Changes will take effect immediately. That’s
because what we’re using here is a method, not a cmdlet. Which means,
unlike with cmdlets,
SetPassword has no support for a
-whatif or a
-confirm.
That’s all there is to it. Let me now show you the steps we’ve discussed here in theory on an actual PowerShell:
2. Restarting or shutting down a server with PowerShell
Let’s now move on to the task of restarting or shutting down a server
using PowerShell. Just like the first task, we’re still going to assume
you’re logged in as a domain administrator on a Windows 7 machine that
belongs to your domain.
For these tasks, we’ll be using a couple of WMI-based cmdlets,
Restart-Computer and
Stop-Computer.
Although we won’t be showing them here, it’s worth mentioning that
these cmdlets accept alternate credentials. Alternate credentials allow
you to specify a user account other than the one you are already logged
into so that you can perform actions that that (alternate) account has
permissions for.
Another thing that’s nice about these cmdlets is that you’ll be able to make use of
-whatif and
-confirm.
That means, if you want to do a restart or a shutdown, you’ll have a
way of making sure you’ll be doing it on the computer you intend to do
it on. This can come in handy if you want to perform restarts or
shutdowns on a number of computers. You can just pipe a list or group of
computers to these cmdlets.
To restart a remote computer or computers, the basic syntax is:
Restart-Computer -ComputerName <string[ ]>,
wherein
-ComputerName <string[ ]> is a string array that can be comprised of the name of a single computer or the names of multiple computers.
Stop-Computer
uses practically the same syntax. So for example, if you want to
restart two computers named CHI-DC02 and CHI-FP01, the command would be:
Restart-Computer “CHI-DC02”, “CHI-FP01”
Here’s an actual PowerShell screenshot wherein we used the
-whatif argument. You use a
-whatif if you simply want to simulate what would happen if you would execute the command in question.

That was pretty straightforward. Let’s now try a more sophisticated
example. Let’s assume you have a list of computers in a file named
servers.txt. You can use the
Get-Content cmdlet to retrieve the contents of that text file, like this:

So, if you have a bunch of computers that you want to restart on a
regular basis, you can list down the names of those computers in a text
file. Then each time you need to restart them, you simply use the
Get-Content cmdlet. Here’s how we used
Get-Content and
Restart-Computer in a real-world scenario:

First, we got the content from the text file using
Get-Content. Then, because we wanted to prepare for the eventuality that some computers would be offline, we piped the list to a
where statement for testing. In the
where statement, we ran
test-connection, which is basically a
ping on each computer.
The
-quiet returns either
true or
false, while
-count 2
means each computer will only be pinged twice. Those computers that
were successfully pinged twice, were then passed along the pipeline.
Next, we used a
foreach. Specifically, the objective
was that: for each name that came out of the ping test, a green-colored
message would be written saying that that computer was “
Restarting”. The
$_ stands for the current object in the pipeline. Next, the
Restart-Computer cmdlet was called to restart each computer that could be pinged. We also used the
-force parameter to kick off anyone logged on.
Finally, we used
-whatif again to see what would happen without having to actually restart those computers.
3. Restarting a service with PowerShell
Restart-Service is the cmdlet used for restarting a
service. Although this cmdlet does not have a built-in mechanism to
connect to a remote computer, PowerShell Remoting can be enabled so that
you can execute it locally via remoting on the remote computer. This
can come in handy when you want to restart a service on a group of
computers.
To restart a service locally, simply say:
Restart-Service “service”,
wherein “service” is the name of the service you want to restart. On
the other hand, if you want to restart a service on one or more remote
machines, then you can use the
Invoke-Command cmdlet and
PowerShell Remoting.
In the PowerShell screenshot below, you see two instances wherein we executed the
Restart-Service cmdlet to restart the service called
wuauserv, which is the Windows Update service. In the first instance,
Restart-Service is executed locally. But in the second instance, it is executed on a remote database server named
CHI-DB01 with the help of the
Invoke-Command.

By default,
Restart-Service doesn’t write any objects in the pipeline unless you use
-passthru. So the additional information you see at the bottom (Status, Name, etc.) is a result of using
-passthru.
If the service runs on multiple computers and you want to restart the
service running there as well, just add more computer names in a
comma-separated list.
Another way to do that same task is by using WMI. First, you create a WMI object:
gwmi is the alias for
Get-WmiObject.
Let me show you first the methods of this object. To do that, we’ll pipe the object to
Get-Member (alias is
gm).

If you notice, there is no method for restarting ther service. That means, we will have to stop the service using the
StopService method and then start it again using the
StartService method.
Here’s how you stop the service using the object’s
StopService method. The parenthesis indicates it’s a method. If you get a
ReturnValue of
0, that means the service stopped successfully. In case you get another
value, you can research what that value means by reading the MSDN
documentation for the Win32 service class.
To fire the service up again, you use the
StartService method.
You can verify by executing the
get-service command for that computer.
Get-service allows
you to connect to a remote computer, so you can simply get that service
from the target computer to verify if it is in fact running there.
4. Terminating a Process with Powershell
Another task that’s commonly done on a server is terminating a process. To terminate a process, you use the
Stop-Process cmdlet. Again, this can be executed locally or, if you want to stop a process on a remote system, you can use
Stop-Process along with
PowerShell Remoting.
There are two ways of terminating a process using the
Stop-Process cmdlet.
The first one is pretty straightforward. You just run the
Stop-Process command
and then pass to it either the name of the process or its corresponding
ID. In the screenshot below, the name of the process being killed is ‘
Calc’ (which is really just the Windows Calculator). Note that
Calc is running locally in this example.

The second involves using the
Get-Process cmdlet to get one or more processes and then piping them to
Stop-Process to kill all those processes at the same time. In the screenshot below, the process being killed is
Notepad. Note that
kill is an alias of
Stop-Process. Again, just like
Calc in the previous example,
Notepad is running locally.

Let’s now move on to an example where we have a process running
remotely. First, let’s fire up a process to kill. So here, we’re
starting
notepad on a remote computer named
chi-fp01.

Next, let’s check whether the process is actually running. For this purpose, we use
ps, which is an alias for
Get-Process.

Ok. Now that we have a remote process to kill, let’s go ahead and kill it. Like what we did in our discussion on
Restarting a Service, we’ll use
Invoke-Command and
PowerShell Remoting to run the
Stop-Process expression on the remote server
chi-fp01.
See how the
Get-Process alias (
ps), which is running in the script block, pipes the process to the
Stop-Process alias (
kill)
.
5. Creating a Disk Utilization Report with PowerShell
As admins, we often need to keep track of how much disk space is
being used on our servers. We can accomplish this using WMI and the
Win32_LogicalDisk class, which will give us information such as the
Device ID, the size of the drive, free space, and a few other bits of
information.
Using WMI, we can query local or remote computers. We can also
perform those queries on either a single or multiple machines. In
addition, we can: export the data we query to a CSV file or a database;
create a text-based or an HTML-based report; or simply display the
output to the screen.
Here’s a sample command using WMI on a local computer.
Get-WmiObject win32_logicaldisk -filter “drivetype=3” | Out-File c:\Reports\Disks.txt
We use the
GetWmiObject cmdlet to return information from the
Win32_LogicalDisk class. Then we employ the
-filter to return only information related to
drivetype=3, which stands for fixed logical disks like the
c:
drive. That means, information regarding USB drives and network drives
are not to be included.The returned information is then piped to a text
file named
Disks.txt.
Here’s a similar example done in an actual PowerShell where we could
see an actual output. Note that we are using aliases to shorten the
command. Also, in this example, we specified that the output would
include the device ID, disk size, the free space, and the system name.

While there’s certainly nothing wrong with that output, it sure could
use a couple of improvements. For example, you might want to display
the size and free space in Gigabytes instead of bytes. We can actually
get a more elegant output by adding a few extra steps. Let me show you
how.
For this purpose, we’re going to create a function named
Get-DiskUtil.
Although the succeeding example is going to show you how to do things
interactively in the shell, you can actually put this function in a
script file, load it into your profile, or load it to your other scripts
so that you can use it again later on.
Here’s the function I’m talking about:

Let’s dissect that function now.
The function is going to take a computer name as its parameter and it will default to the local computer name.

Now we use the
Process script blocks that this
computer name property can be piped-in to the function. If it gets a
piped-in value ($_), then it’s going to set the computer name variable
to that piped-in value. Otherwise, it will take the computer name that
gets piped-in as a parameter.

Next up is the
GetWmiObject expression.

The output of that expression is piped to the
Select-Object cmdlet (represented by its alias,
Select). We then make use of a hashtable to create a custom property called
Computername. This basically renames the
SystemName of the current object ($_) to
Computername. The
DeviceID is passed along as is.

We then deploy a couple more hashtables. The first one takes the
Size property, divides it by 1GB, expresses the result into two decimal points, and renames the property to
SizeGB. The second one takes the
Freespace property and does practically the same thing to it.

Next, we create a new property called
UsedGB, which doesn’t exist in WMI. It simply takes the difference between the
Size and
FreeSpace properties and divides the result by 1GB.

Finally, we also create another property called
PerFree,
which stands for “percent free”. This shows the free space as a
fraction of total disk size expressed in percentage. And that completes
the function.

Here’s the function in action wherein we passed to it the name of the computer, piped the output to
Format-Table (or
ft), and set the final output to auto-size using
-auto.

While all this looks nice and pretty, there’s still a lot more that
we can get from this function. So let’s say that on a weekly basis, you
need to get a disk utilization report of all the servers in your
environment. Here are a couple of different ways you can work with this
data.
The first thing we’re going to do is to save the results of our expression to the variable
$data. That’s so we don’t have to type in the command repeatedly. Next, we pipe the results to the
where object, do the ping tests (pinging it twice when it can be pinged), and then pipe the computer name to our newly-created
Get-DiskUtil function.
You’ll know that the command is done executing when you get the prompt back.

That would mean the data has already been stored in
$data. You can then pipe the information in
$data to sort by
computername and then set it to auto-resize. You can also send that information to
Out-Printer or
Out-File.

Similarly, if you want to load that information to a SQL database or
an Excel spreadsheet, you can convert the data to a CSV file like this:

Later on, if you import that CSV file, you will be able to obtain a
snapshot of the disk utilization status of those disks right at the time
the command is run.

Here’s a portion of that snapshot:

As a final example, let me show you how to create an HTML report that
perhaps you will want to put on your Internet server to show disk
utilization. So that, as an IT admin, you can go ahead and take a quick
peek at your disk utilization status even while you’re outside the
office.
So again, you start by taking $
data and pipe it to
Sort Computername. You then pipe the result to the
ConvertTo-HTML cmdlet. You also give it a title and specify a CSS path. The CSS part is needed because
ConverToHTML does
not do any formatting. So if you want your report to look pretty you’ll
need that CSS file. Finally, you need to send the output to a file.
I have uploaded CSS code below text box.you just copy it and save as .CSS format and give the path to your power shell script.

Now that your file’s ready, you can then look at the file by using the
start command.

Here’s a sample of that HTML report.
Remember that the values on this report are up-to-date.
Thanks
R.karthikeyan