PowerShell Profile Tricks – Random Background Color

The need:  To run multiple PowerShell windows and keep it straight which one is working on what.

Example:

  1. In PowerShell window #1 you’re working with SharePoint
  2. In PowerShell window #2 you’re working with Active Directory users
  3. In PowerShell window #3 you’re goofing off customizing your profile so you can write a blog post

Only problem is, once you’re working with these windows, it’s hard to tell which window was the one you are working on your profile in – because they all look like this:

image image image

Here’s how to alleviate this problem automatically using an awesome PowerShell profile trick

Continue reading “PowerShell Profile Tricks – Random Background Color”

Beginning PowerShell Free Tutorial – Creating Your Profile

Whether you’re new to PowerShell or not, when you find yourself ready to start customizing PowerShell and making it do a few tricks, you’re going to want to setup your profile.

Don’t worry, I will show you how to create your profile, and even show you how to add a few cool things to your profile.  You are about to develop the skills to tame that PowerShell profile!

Advertisement

Continue reading “Beginning PowerShell Free Tutorial – Creating Your Profile”

How To Find Your System Path – Using PowerShell and Environment Variables

Just had a couple techs scratching their heads about finding the path.

Seriously? Yes.

But to be fair, the path can get long and downright hard to read.   And that was the problem for our tech friends.

Now my friends are smart guys, but they had a problem with a path.  I can understand, since my path statement is over 800 characters, and nearly impossible to understand when read the normal way.  They should have learned PowerShell.  I’ll show you why, and it’s a great example of how PowerShell blows away other methods by being super easy and ultra flexible.

Continue reading “How To Find Your System Path – Using PowerShell and Environment Variables”

PowerShell How To Ping a List of Computers

This quick free lesson in PowerShell teaches you how to use the ping class to get a list of offline computers.  It is fast and easy, and the results are much easier to work with than using ping.exe.

Using the .Net Ping Class

PowerShell is built for speed, and it leverages the .Net framework to make this happen. 

To check the computers status, a Ping request is sent to each computer in a list. 

To start pinging, an object of the Ping class is instantiated:

$ping = new-object system.net.networkinformation.ping

Easy, right?

This avoids having to use the sloppy mess of processing through the text returned by ping.exe.

What is the difference?

By using a .Net object for the ping results, we can still use the object that is returned.  We can save the objects themselves and reference them back later.  The beauty of PowerShell.  The Power.  We want (and get) much more information.  The results of

ping 192.168.1.1

is a wall of text (an array of 11 strings, actually,) while the result of

$ping.send(“192.168.1.1”)

Is a .Net object of the "system.net.networkinformation.pingreply” class.  A pingreply has a property (named ‘status’) that tells us if the ping was successful or not; the address of the ping; and the miliseconds that it takes to get the reply.

To get results that are usable, keep your ping replies in a variable of results, like this:

$pingreturns = $ping.send(“192.168.1.1”)

Alright, we’ve got the base now for finding out if the computer is reachable.

Get Your Computer List Ready

The list of computers we want to ping.  You don’t have to limit your list to only computers. If the network device has Internet Control Message Protocol (ICMP) available (most do) and turned on (depends), it will return pings when they are received. You could ping network printers, or routers, for example.

Here are some examples of loading the ping list:

Get Computer List From Textfile

If you have several computers that you want to check frequently, add them to a text file so it’s easy to save, and easy to update the file instead of modifying the script.

“computer1”,”computer2”,”192.168.1.100”,”192.168.1.1” | out-file c:\users\public\documents\pinglist.txt

Now you’ve got a text file.  Quake with fear, bitches!  Note the use of hostnames and IP Addresses.  It’s fine to do that, you can mix and match.  That list is 4 computers, not a collection of 2 computers listed by hostname and IP.

Update the list of computers as needed.

To load the list of computers:

$complist = gc c:\users\public\documents\pinglist.txt

Get Computer List Manually

$complist = “computer1”, “computer2”

Easy, simple, and easy.  To change the list, you’d change it in the script itself. 

Get Computer List From Other Parts Of The Script

$servers = get-qadcomputer –service domain.com *serv*

$complist = $servers | select name

This seems normal, but it’s actually different, because you’re saving a list of objects into $complist, instead of a list of strings.  Here’s the difference

PS C:\ScriptGenius> $stringlist = "Computer1", "Computer2"
PS C:\ScriptGenius> $stringlist[0]
Computer1
PS C:\ScriptGenius> $stringlist[0].gettype()

IsPublic IsSerial Name                                     BaseType
——– ——– —-                                     ——–
True     True     String                                   System.Object

Compare that to the item in the object list

PS C:\ScriptGenius> $objectlist = get-qadcomputer *work* | select name
PS C:\ScriptGenius> $objectlist[0]

Name
—-
SOFTGRIDWORK2

PS C:\ScriptGenius> $objectlist[0].gettype()

IsPublic IsSerial Name                                     BaseType
——– ——– —-                                     ——–
True     False    PSCustomObject                           System.Object

While the two seem at first to be the same:

$ping.send($stringlist[0])

Works.

$ping.send($objectlist[0])

Does not, but it is at least salvageable.  To make that ping work,  the name property of the psCustomObject (the computer account returned by get-qadcomputer) must be referenced.

$ping.send($objectlist[0].name)

Works.

Get Computer List From an IP Range

This will do an IP sweep for a subnet, pinging along the way.

1..254 | % {$ping.send(“192.168.1.$_”) | select address, status}

Putting it All Together

Now that we’ve seen the pieces, here’s how it all works together.

$computers = get-content C:\scriptgenius\computers.txt

$ping = new-object system.net.networkinformation.ping

$pingreturns = @()

foreach ($entry in $computers) {

  $pingreturns += $ping.send($entry)

}

An array is used here to collect multiple ping results.  When completed, this can be used like this.

$pingreturns[4].status

or

$pingreturns | ? {$_.status –ne “success”} | select address

Instead of piping that to “select address” we could just as easily take action on those failed IP addresses.  Like sending the list of offline computers to the administrative team on on-call person via email.

How to Use PowerShell to Create a Stopwatch and Alarm

So you want a quick and easy stopwatch with PowerShell to time how long you’ve been at a task?  Want to see how long it takes for your coworkers to realize you’re awesome?  Would you like to use PowerShell as a timer or alarm clock?   You can easily use PowerShell to keep track of how long an antivirus scan or checkdisk is taking on another system!

PowerShell contains many of the .NET class library by default, but there are thousands more waiting for you to connect them.

The Stopwatch class is available as part of the System.Diagnostics namespace. To gain access to the classes in it you have to load the namespace.

[System.Reflection.Assembly]::LoadWithPartialName(“System.Diagnostics”)

Once loaded, you can create a stopwatch object.

$sw = new-object system.diagnostics.stopwatch

now that you’ve got your stopwatch, you have access to the methods and properties of the stopwatch class:

Method
Usage
Notes
Start $sw.start() Begin the stopwatch counting
Stop $sw.stop() Stops the stopwatch counting
Reset $sw.reset() Stops the counter and sets elapsed to zero

 

Property
Usage
Notes
IsRunning $sw.IsRunning Returns True/False
Elapsed $sw.Elapsed Returns all elapsed information
.Days $sw.elapsed.days Integer (Int32) days
(how many whole days)
.Hours $sw.elapsed.hours Int32 Hours
.Minutes $sw.elapsed.minutes Int32 Minutes
.Seconds $sw.elapsed.seconds Int32 Seconds
.Milliseconds Int32 Milliseconds
.Ticks Int64 Ticks
.TotalDays You get the point
.TotalHours and
.TotalMinutes this table is getting
.TotalSeconds crowded
.TotalMilliseconds
ElapsedTicks $sw.elapsedticks does not require “elapsed.ticks”
ElapsedMilliseconds $sw.elapsedmilliseconds does not require “elapsed.milliseconds”
Excellent, dude.  I now know one more useless thing to do with PowerShell.

Wrong!  you now know 2 useless things to do with PowerShell:

Tracking Time and Setting Alarms

A note about this:  There IS a measure-command cmdlet in Powershell, which is great because it automatically starts the timer when the command starts, and ends it when the command is over.  But there are some drawbacks to using measure-command:

  • Output is suppressed, like this:

get-qaduser domain\me

returns my acct, but:

”measure-command {get-qaduser domain\me }”

returns the time it takes to get my acct. It does not output my user account to the screen.

  • It runs on only one script block.  If you want to time several commands, or check to see how long a whole process takes (especially if you have an external force like a coworker or other department) a measure-command isn’t going to work.

Things you can time: Here is just a small sample of things you can time.

  1. Your coworkers breaks (but not your own, right?)
  2. How long a Chkdisk or Defrag runs on a machine.
  3. How long it takes your coffee go cool off (or your Mountain Dew to warm up – try doing THAT with measure-command.
  4. How long it takes to parse through enormous lists of users/computers/anything else.

How to set an alarm: Want to work on a project for 20 minutes?  Or how bout start playing an annoying song 15 minutes after you leave for lunch?

while ($sw.elapsed.minutes –lt 20) {$null}; invoke-item “C:\users\public\Music\Sample Music\kalimba.mp3”

3 parts really make this work.

1) (elapsed.minutes -lt 20)  –  We identify our alarm time – in this case “don’t do anything until the timer hits 20 minutes”.

2) {$null}  – While we’re waiting we just do nothing.

3) invoke-item c:\music.mp3 – “invoke-item” means open the file with it’s default program – for me it plays in Media Player, or Winamp – depending on what machine I’m on.  

When the music plays, you know the timer is up!

ilovepowershell.com Quick-Commands:

Load the diagnostic objects:
[System.Reflection.Assembly]::LoadWithPartialName(“System.diagnostics”)

Create a stopwatch:
$sw = new-object system.diagnostics.stopwatch

Create an alarm:
while ($sw.elapsed.minutes –lt 20) {$null}; invoke-item “c:\users\public\music\sample music\kalimba.mp3”

All Praise To God

Dear God,

Thank you for blessing me with a love of learning and problem solving.  Because of the gifts you have given me, I am able to pass on these gifts to others.

I dedicate this site to you, and it is for you that I work and learn.  It is on your behalf that I spread the word through PowerShell.  Please bless this site to be a place where my technical friends can learn PowerShell and develop their scripting skills.  And please bless the readers of this site with a deeper understanding of not only PowerShell, but please come into their lives and bless them, too.

Thank you for all you do,

Michael