Category Archives: Quick Learn

Practical examples of PowerShell concepts gathered from specific projects, forum replies, or general PowerShell use.

PSMonday #41: February 6, 2017

Topic: Do-Until

Notice: This post is a part of the PowerShell Monday series — a group of quick and easy to read mini lessons that briefly cover beginning and intermediate PowerShell topics. As a PowerShell enthusiast, this seemed like a beneficial way to ensure those around me at work were consistently learning new things about Windows PowerShell. At some point, I decided I would share these posts here, as well. Here’s the PowerShell Monday Table of Contents.

I said I would say it this week too, so let’s get it out of the way: The Do-While and Do-Until loops ensure that the statement list is run at least once. Your code is going to execute at least one time using a Do construct. This is because the condition, that determines whether or not we loop again, isn’t evaluated until the statement list has run once. If you need to ensure your code executes at least one time, then the Do-While and Do-Until variations of the Do loop, may be the language construct you need.

Here’s the conceptual examples of the Do-Until.

Do {<statement list>} Until (<condition>)

Do {
    <statement list>

} Until (<condition>)

Our first below example should look somewhat familiar. We saw it first last week in the Do-While examples. We assign 1 to the $Number variable and then enter the Do loop. We output a string statement and then increment the $Number variable. Then, we check the condition. The condition indicates that we’ll continue to loop until $Number is less than 10. Well, 1 is always less than 10, so we exit the construct. This is a clear example that we always run the statement list at least once in a Do loop, before we check the condition.

$Number = 1

Do {
    Write-Output -InputObject "In the Do loop ($Number)."
    $Number++

} Until ($Number -lt 10)

In the Do loop (1).

Let’s modify this example. We’ll reinitialize the $Number variable back to 1 and start again. This time our condition states that we’ll continue to loop until $Number is greater than 10. As $Number is lower, you can likely guess that we’re going to run through this loop several times. Ten times, to be exact.

$Number = 1

Do {
    Write-Output -InputObject "In the Do loop ($Number)."
    $Number++

} Until ($Number -gt 10)

In the Do loop (1).
In the Do loop (2).
In the Do loop (3).
In the Do loop (4).
In the Do loop (5).
In the Do loop (6).
In the Do loop (7).
In the Do loop (8).
In the Do loop (9).
In the Do loop (10).

In closing out the Do variations, we’ll add a final example. Much like last week, we’ll transition from using numeric values to date times. In this example, we’ll add 10 seconds to the current time. Then, we’ll output a string value and sleep (pause) for a second. Eventually, the current time will be greater than the time when we began; therefore, the condition will be $true and we’ll exit the looping construct.

$Time = (Get-Date).AddSeconds(10)

Do {
    Write-Output -InputObject 'Waiting for time to pass...'
    Start-Sleep -Seconds 1

} Until ((Get-Date) -ge $Time)

Waiting for time to pass...
Waiting for time to pass...
Waiting for time to pass...
Waiting for time to pass...
Waiting for time to pass...
Waiting for time to pass...
Waiting for time to pass...
Waiting for time to pass...
Waiting for time to pass...
Waiting for time to pass...

Next week is our final language construct — the While loop. By then, you’ll have a full and complete understanding of the various control structures we can use to respond to conditions in PowerShell. In case you hadn’t considered it, learning these concepts — even if it’s with PowerShell — is going to make learning other scripting, and even programming languages, easier to do.

PSMonday #40: January 30, 2017

Topic: Do-While

Notice: This post is a part of the PowerShell Monday series — a group of quick and easy to read mini lessons that briefly cover beginning and intermediate PowerShell topics. As a PowerShell enthusiast, this seemed like a beneficial way to ensure those around me at work were consistently learning new things about Windows PowerShell. At some point, I decided I would share these posts here, as well. Here’s the PowerShell Monday Table of Contents.

Next up on our language construct journey, is part one of the Do loop: the Do-While. Once you’ve read this week’s, and next week’s PSMonday, be sure to read the full about help topic using the below command.

Get-Help -Name about_Do -ShowWindow

Here’s a couple conceptual examples of the Do-While loop. Of the two, you’ll see me use the second example, in order that my code is easier to read.

Do {<statement list>} While (<condition>)

Do {
    <statement list>

} While (<condition>)

For our first example, we’ll start looping based on the value of a variable. We begin by assigning the numeric value of 1 to the $Number variable. This assignment is done outside of the looping construct. Once set, we begin the loop. On the first pass, we indicate that we’re in the loop, as well as the current value of the $Number variable, we then increase the value of the $Number, and then we check if it is less than (-lt) the numeric value of 10. While this condition is true, we’ll continue to loop, incrementing the value in $Number each time, until the value in $Number variable is no longer less than 10.

$Number = 1

Do {
    Write-Output -InputObject "In the Do loop ($Number)."
    $Number++

} While ($Number -lt 10)

In the Do loop (1).
In the Do loop (2).
In the Do loop (3).
In the Do loop (4).
In the Do loop (5).
In the Do loop (6).
In the Do loop (7).
In the Do loop (8).
In the Do loop (9).

Instead of using a numeric value condition, this time, we’ll use a datetime object instead. Take a look at this next example, and then follow the further below description of each task within the example.

"Current Time: $((Get-Date).ToString())"

$Time = (Get-Date).AddSeconds(10)

"Future Time : $($Time.ToString())"

Do {
    Write-Output -InputObject '--> Waiting for time to pass.'
    (Get-Date).ToString()
    Start-Sleep -Seconds 1

} While ((Get-Date) -lt $Time)

"Current Time: $((Get-Date).ToString())"

Current Time: 1/29/2017 1:46:20 PM
Future Time : 1/29/2017 1:46:30 PM
--> Waiting for time to pass.
1/29/2017 1:46:20 PM
--> Waiting for time to pass.
1/29/2017 1:46:21 PM
--> Waiting for time to pass.
1/29/2017 1:46:22 PM
--> Waiting for time to pass.
1/29/2017 1:46:23 PM
--> Waiting for time to pass.
1/29/2017 1:46:24 PM
--> Waiting for time to pass.
1/29/2017 1:46:25 PM
--> Waiting for time to pass.
1/29/2017 1:46:26 PM
--> Waiting for time to pass.
1/29/2017 1:46:27 PM
--> Waiting for time to pass.
1/29/2017 1:46:28 PM
--> Waiting for time to pass.
1/29/2017 1:46:29 PM
Current Time: 1/29/2017 1:46:30 PM

We began the above example by echoing the current date and time. Then we created the $Time variable and made use of the AddSeconds() method to store the date and time 10 seconds into the future. So we know that time, we echoed it to the screen, as well.

Next, we entered the Do-While construct. Our statement list included writing a string to indicate that we we’re waiting for time to pass, writing the current date and time, and then sleeping for one second. Once these commands were completed, we checked the current date and time as a part of the Do-While’s condition. If the current time was still less than (-lt) ten seconds in the future from when we started ($Time), then we looped again. When that condition was eventually met — when the current time was no longer less than that future time — we exited the Do-While statement and echoed the current time.

We’ll cover the Do-Until next week — a language construct variation that you should probably already be able to figure out based on today’s PSMonday. I’ll say it today and next Monday, as well: The Do loops — both Do-While and Do-Until — ensure that we’ll go through the statement list at least one time. This is to say, that the condition is not evaluated until your code has been executed at least once.

PSMonday #39: January 23, 2017

Topic: For

Notice: This post is a part of the PowerShell Monday series — a group of quick and easy to read mini lessons that briefly cover beginning and intermediate PowerShell topics. As a PowerShell enthusiast, this seemed like a beneficial way to ensure those around me at work were consistently learning new things about Windows PowerShell. At some point, I decided I would share these posts here, as well. Here’s the PowerShell Monday Table of Contents.

This week we’ll discuss the For loop. The first of the two below commands can be used to open the For help file. Inside the file you’ll find the command layout, as we’ve seen with the other language constructs, and cmdlets. The way I write the For language construct, has been included below.

Get-Help -Name about_For -ShowWindow

For (<init>; <condition>; <repeat>) {
    <statement list>
}

The For loop begins with the For keyword and a set of parenthesis. Inside the parenthesis is an initialization (listed as init above), followed by a semi-colon. Following the initialization, we include a condition. By now, you undoubtedly realize there will always be some sort of required condition within our language constructs. Foll­owing the second semi-colon, we have a way to increment our initialization variable, as an assurance we’ll loop through the For loop as many times as is indicated by our condition. This may make more sense, very shortly.

We’re only going to look at a single example for the For loop, but we’ll be sure to highlight all the key features, as well as fully walk through the example. Take a look at the below example, and then we’ll discuss it thoroughly.

For ($i = 1; $i -le 10; $i++) {
    "The value of the `$i variable is $i."
    Start-Sleep -Seconds 1
}

We begin our For statement by entering the For keyword, followed by a set of parenthesis. To initialize the For construct, we’ll set a variable, $i, to the numeric value of 1, as $i = 1. We could have used a different number, however, it would require some changes in the areas we’ll discuss next. We could’ve use a different variable, too, had we opted to do so.

Our condition, $i -le 10, indicates to continue to loop through this For construct, so long as $i is less than, or equal to, 10. The final value in the parenthesis, $i++, increments the value in $i by 1, for each loop iteration. It’s shorthand for $i = $i + 1. Inside the curly brackets is where we enter our statement(s); this is where we do our work. In our example, we’ll echo a string that includes the value of the $i variable, and then sleep, or pause, for one second. Here’s the results of our example.

The value of the $i variable is 1.
The value of the $i variable is 2.
The value of the $i variable is 3.
The value of the $i variable is 4.
The value of the $i variable is 5.
The value of the $i variable is 6.
The value of the $i variable is 7.
The value of the $i variable is 8.
The value of the $i variable is 9.
The value of the $i variable is 10.

There’s some confusion about when to use a foreach variation (foreach and ForEach-Object), and the For construct. I use For when I know how many times I need to loop, as this is a requirement. If you know this piece of information, then you might consider the For loop over the other two looping constructs we’ve discussed thus far. Think back to foreach and ForEach-Object: the number of times we were going to loop, was never a consideration before we began.

We’ll be back next Monday where we’ll cover another looping construct: the Do-While loop.

PSMonday #38: January 16, 2017

Topic: Foreach-Object II

Notice: This post is a part of the PowerShell Monday series — a group of quick and easy to read mini lessons that briefly cover beginning and intermediate PowerShell topics. As a PowerShell enthusiast, this seemed like a beneficial way to ensure those around me at work were consistently learning new things about Windows PowerShell. At some point, I decided I would share these posts here, as well. Here’s the PowerShell Monday Table of Contents.

We’re back today to wrap up the ForEach-Object cmdlet, with a few additional examples.

The Get-PSDrive cmdlet’s purpose is to return the logical drives on the computer, to include mapped drives, as well as drives exposed by various PowerShell providers. These include the alias drive — where the aliases are stored — the function drive — where functions in the current session are stored, and current user and local machine hives in the registry, as HKCU and HKLM, respectively.

Therefore, if you didn’t already know, you can search the registry from inside PowerShell, just as if it were a drive on the computer. That’s the purpose of a PSProvider. It can present various data stores, as though they were drives on the computer.

Here’s a filtered Get-PSDrive command, and the results it produces.

Get-PSDrive | Select-Object -Property Name,Root

Name     Root
----     ----
Alias
C        C:\
Cert     \
D        D:\
Env
Function
HKCU     HKEY_CURRENT_USER
HKLM     HKEY_LOCAL_MACHINE
S        S:\
Variable
WSMan

We did something like the upcoming example when we learned about the foreach language construct. In this example, we’ll deconstruct the objects produced by Get-PSDrive, in order to write out strings based on two properties of the objects — Name and Root. You probably wouldn’t want to do this, but nonetheless this example offers us a collection to loop through with the ForEach-Object cmdlet.

Get-PSDrive | ForEach-Object {
    "PSDrive Name : $($_.Name) || Root: $($_.Root)"
}

PSDrive Name : Alias || Root:
PSDrive Name : C || Root: C:\
PSDrive Name : Cert || Root: \
PSDrive Name : D || Root: D:\
PSDrive Name : Env || Root:
PSDrive Name : Function || Root:
PSDrive Name : HKCU || Root: HKEY_CURRENT_USER
PSDrive Name : HKLM || Root: HKEY_LOCAL_MACHINE
PSDrive Name : S || Root: S:\
PSDrive Name : Variable || Root:
PSDrive Name : WSMan || Root:

The next example begins by assigning the $Numbers variable a range of values from 1 to 10, thus making this variable an array.

$Numbers = 1..10
$Numbers

1
2
3
4
5
6
7
8
9
10

In each of the next two examples, we’ll make use of our numbers variable. This first example will use the foreach language construct that we covered prior to the ForEach-Object cmdlet. We set up the foreach using the foreach keyword and use $Number (singular), to use as the current value in the array.

Foreach ($Number in $Numbers) {

    Write-Output -InputObject "The current number is $Number."
}

The current number is 1.
The current number is 2.
The current number is 3.
The current number is 4.
The current number is 5.
The current number is 6.
The current number is 7.
The current number is 8.
The current number is 9.
The current number is 10.

In the below example, we’ll do the exact same thing as we did above, and iterate though each member in an array. The ForEach-Object cmdlet can do the same thing as the foreach language construct, it just does it a little differently. Instead of a variable you choose, we use $_, or $PSItem. Instead of foreach being the first word in the command, we pipe to the ForEach-Object cmdlet.

$Numbers | ForEach-Object {

    Write-Output -InputObject "The current number is $_."
}

The current number is 1.
The current number is 2.
The current number is 3.
The current number is 4.
The current number is 5.
The current number is 6.
The current number is 7.
The current number is 8.
The current number is 9.
The current number is 10.

In closing out ForEach-Object, let’s discuss some final differences with it, and the foreach language construct.

The foreach language construct is faster than the ForEach-Object cmdlet. This is because foreach puts the entire collection into memory before it begins to iterate over each item in the collection. This could be a problem, however, if there’s a chance you’ll run out of memory before you’re done processing the entire collection. While the ForEach-Object cmdlet may be slower, it’ll consume less memory.

We’ll continue with the For loop, next Monday.

PSMonday #37: January 9, 2017

Topic: Foreach-Object

Notice: This post is a part of the PowerShell Monday series — a group of quick and easy to read mini lessons that briefly cover beginning and intermediate PowerShell topics. As a PowerShell enthusiast, this seemed like a beneficial way to ensure those around me at work were consistently learning new things about Windows PowerShell. At some point, I decided I would share these posts here, as well. Here’s the PowerShell Monday Table of Contents.

Now that we have a basic understanding of the foreach language construct, we can move on to the ForEach-Object cmdlet. First, let’s consider the name of the cmdlet, as there are some similarities with some others. The noun — remember the verb-noun naming convention — is object. Let’s find all the commands with that same noun.

Get-Command -Noun Object | Select-Object CommandType,Name

CommandType Name
----------- ----
   Function Show-Object
     Cmdlet Compare-Object
     Cmdlet ForEach-Object
     Cmdlet Group-Object
     Cmdlet Measure-Object
     Cmdlet New-Object
     Cmdlet Select-Object
     Cmdlet Skip-Object
     Cmdlet Sort-Object
     Cmdlet Tee-Object
     Cmdlet Where-Object

If you’ve used some of the above commands, then you may recognize that many of these commands are used with the pipeline. This is to say, that we often send a command’s resulting objects to one of these commands.

In fact, take a look at the Get-Command, command we ran: We piped the objects created by Get-Command to the Select-Object cmdlet for further processing and filtering. That’s how we’ll use ForEach-Object, too; we’re always going to pipe to it.

Let’s begin with some conceptual examples of the ForEach-Object cmdlet. As we saw in a previous PSMonday, the first part of this example is the Microsoft help’s suggestion, and the second part of this example is how you’ll see me use the cmdlet.

<command> | ForEach-Object {<command_block>}

<command> | ForEach-Object {
    <command_block>
}

As we’ve stated before, always use full cmdlet names unless you’re using the command in a onetime use scenario. If you’re pounding out PowerShell commands with no intention of keeping them, then you can use either of the ForEach-Object aliases, as demonstrated below. This is important: foreach is an alias for the ForEach-Object cmdlet when it is used in a pipeline. When it’s not used in a pipeline, such as we saw in the last two weeks, it’s treated as the foreach language construct, and not as an alias for ForEach-Object. This can cause some confusion, and so it’s important to understand this distinction.

<command> | foreach {
    <command_block>
}

<command> | % {
    <command_block>
}

Before we put things back on hold until next Monday, let’s take a look at a real-world example. Both of the following parts of this example do nearly the same thing. The difference is that one, the second half includes the string “Item: ,” and two, it uses the $PSItem automatic variable, instead of $_. This variable — regardless of which you use — represents the current object in the pipeline. $PSItem was introduced in PowerShell 3.0.

1,'string1',2,'string2' | ForEach-Object {
    Write-Output -InputObject $_
}

Write-Output -InputObject '------'

3,'string3',4,'string4' | ForEach-Object {
    Write-Output -InputObject "Item: $PSItem"
}

1
string1
2
string2
------
Item: 3
Item: string3
Item: 4
Item: string4

In the above example, we sent four objects — two integers and two strings — down the pipeline to each of the ForEach-Object cmdlet examples. In looking at the first part of the example, $_ was 1 the first time the ForEach-Object cmdlet ran, it was ‘string1’, the second time the ForEach-Object cmdlet ran, 2 the third time, and ‘string2’ the final time the loop executed.

We’ll be back next week to help solidify how we use the ForEach-Object cmdlet.

PSMonday #36: January 2, 2017

Topic: Foreach II

Notice: This post is a part of the PowerShell Monday series — a group of quick and easy to read mini lessons that briefly cover beginning and intermediate PowerShell topics. As a PowerShell enthusiast, this seemed like a beneficial way to ensure those around me at work were consistently learning new things about Windows PowerShell. At some point, I decided I would share these posts here, as well. Here’s the PowerShell Monday Table of Contents.

Back again to discuss, and close out, the foreach language construct. This is the first looping construct we’ve seen so far.

Today, one of the things we’ll do, is nest a foreach inside of a foreach. In case it hasn’t been mentioned yet, all of these language constructs can be nested inside of each other. In fact, this is often a requirement. It all depends on the problem, or problems, that you need to solve. This is a great reason to ensure you understand all of the conditional constructs.

We’ll start today’s PSMonday by creating two variables. One, the Colors variables will hold the same four colors from last week. The second variable, the Animals variable, will also hold four values: dog, cat, bird, and frog. Take a look at the below example, and the explanation further below.

$Colors = 'red','blue','green','gray'
$Animals = 'dog','cat','bird','frog'

Foreach ($Color in $Colors) {
    Write-Output -InputObject $Color

    Foreach ($Animal in $Animals) {
        Write-Output -InputObject $Animal
    }
}

red
dog
cat
bird
frog
blue
dog
cat
bird
frog
green
dog
cat
bird
frog
gray
dog
cat
bird
frog

Admittedly, this is a little difficult to follow. Before we walkthrough what’s happening here, let’s modify how we display the values in the Color variable. Additionally, we’ll modify how we display the values in the Animal variable, as well. This will help us better follow these nested foreach loops. Colors will have two dashes on both sides, and animals will have a right, angle bracket before the animal name.

Foreach ($Color in $Colors) {
    Write-Output -InputObject "--$Color--"

    Foreach ($Animal in $Animals) {
        Write-Output -InputObject "> $Animal"
    }
}

--red--
> dog
> cat
> bird
> frog
--blue--
> dog
> cat
> bird
> frog
--green--
> dog
> cat
> bird
> frog
--gray--
> dog
> cat
> bird
> frog

From the previous examples, you may already be able to determine exactly what’s happening. In case you don’t, let’s walk through the looping that is taking place.

After we set the two variables, Colors and Animals, we enter the first foreach. In here, we echo the first color. Then we enter the nested, or the second foreach loop, and loop through all four animals. We then return to the outermost foreach, and echo the second color. Again, we loop through all the animals. We continue this until we’re all out of the colors in the Color variable, and we do a final loop through the animals.

Here’s the last example. Although we won’t be working with nested foreach loops, I think it’s important to see a potential, real-world example. With Get-Service, and most other properly written cmdlets and functions, we can pipe to the Select-Object cmdlet, and return just the properties in which we’re interested.

Get-Service | Select-Object -Property Name,Status -First 3

Name                       Status
----                       ------
AdobeARMservice           Running
AdobeFlashPlayerUpdateSvc Stopped
AeLookupSvc               Stopped

Let’s assume we don’t want to return objects — for some reason — and instead just want to return strings made up of the two above properties, separated by a colon. It’s not really practical, but it will provide a bit more of a real-world foreach example. To accomplish this, we’d need to loop though the results of Get-Service.

Foreach ($Service in Get-Service | Select-Object -First 3) {
    "$($Service.Name) : $($Service.Status)"
}

AdobeARMservice : Running
AdobeFlashPlayerUpdateSvc : Stopped
AeLookupSvc : Stopped

As we can see, the items in our collection (the $Service in Get-Service), can be taken directly from the results of a command, without the need to assign everything to a variable first. While this made not always be the best idea for the sake of readability, it’s something you may see one day.

Up next week, is the ForEach-Object cmdlet.

PSMonday #35: December 26, 2016

Topic: Foreach

Notice: This post is a part of the PowerShell Monday series — a group of quick and easy to read mini lessons that briefly cover beginning and intermediate PowerShell topics. As a PowerShell enthusiast, this seemed like a beneficial way to ensure those around me at work were consistently learning new things about Windows PowerShell. At some point, I decided I would share these posts here, as well. Here’s the PowerShell Monday Table of Contents.

A day late, but here we go.

Like the If statement, the foreach statement is an often used language construct. In fact, I wouldn’t be surprised to find out that it was the second most used, right after the If statement. The foreach differs, however, in that it is a looping construct. This is to say that we use it to loop through a collection, or a group, of items.

As we’ve done in the past, let’s start with the conceptual format of the foreach construct. There’s always a few ways to write the same thing. The first part of this example, shows how it’s displayed in the PowerShell help, and the second part, is how I write, my foreach statements.

foreach ($<item> in $<collection>){<statement list>}

Foreach ($<item> in $<collection>) {
    <statement list>
}

The most common collection we’ll loop through using a foreach is an array. An array is a data structure, designed to store a collection of items. Before we get there, consider that many variables are only ever assigned a single value, such as in the below example.

$Computer = 'Server01'
$Computer

Server01

In the previous example, the Computer variable only held a single, string value of “Server01.”

An array lets us get away with a single variable holding multiple values. Let’s start with the multiple values of ‘red’, ‘blue’, ‘green’, and ‘gray’. Each of these is an item, but together, they are a collection; they’re an array. Before we actually work with this array, we’ll assign it to the Colors variable. The decision to use a plural variable, is intentional.

$Colors = 'red','blue','green','gray'
$Colors

red
blue
green
gray

With this variable set, we can loop through each item in the collection — each value in the variable — using foreach. The first time we enter the foreach, the Color variable (singular), will be ‘red.’ The second time we loop through, the Color variable is ‘blue.’ The third iteration into the foreach, it’s ‘green,’ and on the final pass, the Color variable is ‘gray.’

Foreach ($Color in $Colors) {
    Write-Output -InputObject "The `$Color variable is: $Color"
}

The $Color variable is: red
The $Color variable is: blue
The $Color variable is: green
The $Color variable is: gray

This item variable, could’ve been any word; however, we chose to use Color, because it made the most sense. The decision to use a single variable was intentional, too. Here’s the same example as above, however, we’ve changed Color to Hamburger. It makes no sense, but it still works.

Foreach ($Hamburger in $Colors) {
    Write-Output -InputObject "The `$Hamburger variable is: $Hamburger"
}

The $Hamburger variable is: red
The $Hamburger variable is: blue
The $Hamburger variable is: green
The $Hamburger variable is: gray

We’ll likely wrap up the foreach language construct next week, just in time to work with the ForEach-Object cmdlet. They’re different.

Use Foreach When it’s Really Needed

We’re not all the same, but if we were, and you were like me, you’d have a huge number of tabs open in your browser of choice. Each of them, would have some relation to PowerShell and each would be sitting by idle, and waiting to be read. No idea where it came from, but in one of them last week, I saw this:

Get-Date -Format o | foreach {$_ -replace ":", "."}

I stared at it for a moment, and thought, why is someone piping Get-Date to foreach? Get-Date only returns a single value. Why would that need to be handed off to a looping construct? The point here is, it wouldn’t need to be, even though it works. I’ve decided I should bring this up, in case someone else is potentially going to make this same mistake. Even if you’re a Systems Administrator, you’re still going to want to write efficient, and well thought out code. Here’s how I would have expected to see this written:

(Get-Date -Format o) -replace ":", "."

Again, Get-Date is only going to provide a single returned value, and therefore, we can trust that we don’t need to loop through a set of results. It’s cleaner code, it’s tighter code, and it gives the rest of us some confidence that you’ve thought things through.

One of the things I enjoying doing is testing the speed of various ways to do the same thing. Don’t think for a minute that I didn’t do that here. This next example indicates the time to run the foreach version of this Get-Date command. The second example, indicates the time to run when foreach is not used.

Milliseconds Ticks
------------ -----
           1 19094
           1 10543
           0  7044
           0  4212
           0  3944
           0  3849
           0  4133
           0  4349
           0  4099
           0  3948
Milliseconds Ticks
------------ -----
           1 12386
           0  5277
           0  4438
           0  2479
           0  2345
           0  2325
           0  4003
           0  2352
           0  2335
           0  2311

The times are close; they’re indistinguishable to us humans, but the numbers don’t lie. There’s a better way based both on time to complete, and competency. If you wanted to see it, here’s what I used to measure these two different commands. Keep these things in mind, and keep on learning!

1..10 | ForEach-Object {
    Measure-Command -Expression {
        Get-Date -Format o | foreach {$_ -replace ":", "."}
    } | Select-Object -Property Milliseconds,Ticks
}

1..10 | ForEach-Object {
    Measure-Command -Expression {
        (Get-Date -Format o) -replace ":", "."
    } | Select-Object -Property Milliseconds,Ticks
}

PSMonday #34: December 19, 2016

Topic: Switch Statement IV

Notice: This post is a part of the PowerShell Monday series — a group of quick and easy to read mini lessons that briefly cover beginning and intermediate PowerShell topics. As a PowerShell enthusiast, this seemed like a beneficial way to ensure those around me at work were consistently learning new things about Windows PowerShell. At some point, I decided I would share these posts here, as well. Here’s the PowerShell Monday Table of Contents.

Here we are again. It’s Monday morning and we’re discussing the Switch language construct; we’re wrapping it up, in fact. Last week we determined that Switch included a Wildcard parameter. Today we’ll discuss the Regex parameter, and a bit more.

The below example does a few things. To make this as easiest as possible to follow, I’ve numbered both the list, and the matching code:

  1. Write a string to the host (the screen), to help indicate what the user should do.
  2. Create a prompt to accept the user’s input, and assign that user’s input, to the LastName variable.
  3. Help the user determine their Human Resource representative using a Switch construct and the Regex parameter.
# 1
Write-Output -InputObject 'Enter your last name to determine your Human Resources representative.'

# 2
$LastName = Read-Host -Prompt 'Enter your last name'

# 3
Switch -Regex ($LastName.ToLower()) {
    '^[a-g]' {"Please see Barbara in Room 202."}
    '^[h-m]' {"Please see Mark in Room 203."}
    '^[n-z]' {"Please see Allison in Room 204."}
    default {"$LastName did not work, please try again."}
}

In #3, we’ve set up the Switch statement the same as the other examples; however, we’ve included the Regex parameter. Additionally, the test-value uses the ToLower method, against the value stored in the LastName variable. This ensures our value is in lowercase before we start checking the conditions inside the Switch.

What these conditions do is check the first letter of the last name. Depending on the letter, it’ll report the proper HR representative to visit. One of the things that this example also includes is a default condition. While I could’ve mentioned this week’s ago, I’ve saved it. This is the action to take if there’s no conditional match. Think of this as the Else in an If-Else statement. This could’ve have been included in any of the previous Switch statements we’ve seen in the last three weeks.

Now for the last two examples before we close out the Switch. The $_ variable is something we usually only see when we use ForEach-Object — an upcoming language construct. Even so, it has a purpose in the Switch construct, too. In the below example, it’s acting as the current element in the array. It’s ‘one,’ the first time we enter the Switch, it’s ‘two,’ the second time, etc. Take a look at the example and make sure you can determine why the results were returned the way they were. $PSItem was introduced in PowerShell 3.0, and it does the exact same thing as $_.

$Array = 'one','two','three','four','five'

Switch ($Array) {
    {$_ -eq 'one'} {'One found.'}
    {$PSItem  -eq 'three'} {'Three found.'}
    {$_ -eq 'six'} {'Six found.'}
}

One found.
Three found.

This final example is here to help indicate that we can use the $_, or $PSItem, in both the condition, as we saw above, and in the action, as we’ll see below.

$Servers = 'DC01','DC02','DC03','WEB01'

Switch ($Servers) {
    'DC01'{"Run command against server $_."}
    'DC02' {"Run command against server $_."}
    'WEB01' {"Run command against server $_."}
    {$_} {"Add computer to log file ($_)."}
}

Run command against server DC01.
Add computer to log file (DC01).
Run command against server DC02.
Add computer to log file (DC02).
Add computer to log file (DC03).
Run command against server WEB01.
Add computer to log file (WEB01).

In closing, I should remind everyone that I can’t cover everything about a topic, and so it’s important to finalize your learning, or reviewing, by reading the full about file. You can read about the Switch statement here: Get-Help -Name about_Switch -ShowWindow. Most of it will be a review.

PSMonday #33: December 12, 2016

Topic: Switch Statement III

Notice: This post is a part of the PowerShell Monday series — a group of quick and easy to read mini lessons that briefly cover beginning and intermediate PowerShell topics. As a PowerShell enthusiast, this seemed like a beneficial way to ensure those around me at work were consistently learning new things about Windows PowerShell. At some point, I decided I would share these posts here, as well. Here’s the PowerShell Monday Table of Contents.

In case you haven’t noticed, I really like the Switch statement. Let’s start today’s PSMonday with this first example. It’s dead simple, and really only here for two reasons. One, it indicates we can use the semi-colon between sets of conditions and actions, and two, because I want to indicate the importance of the break statement. After the Switch finds its match in the third condition, it’s going to continue to check the other 23 conditions.

Switch ('c') {
    'a' {'A'}; 'b' {'B'}; 'c' {'C'}; 'd' {'D'}; 'e' {'E'}
    'f' {'F'}; 'g' {'G'}; 'h' {'H'}; 'i' {'I'}; 'j' {'J'}
    'k' {'K'}; 'l' {'L'}; 'm' {'M'}; 'n' {'N'}; 'o' {'O'}
    'p' {'P'}; 'q' {'Q'}; 'r' {'R'}; 's' {'S'}; 't' {'T'}
    'u' {'U'}; 'v' {'V'}; 'w' {'W'}; 'x' {'X'}; 'y' {'Y'}
    'z' {'Z'}
}

C

Let’s avoid that unnecessary work. In this example, after it hits the correct condition, it’ll leave the Switch statement. While there’s not much time savings in this example, there could be, if the Switch was doing more actions than simply echoing a letter to the screen. That’s something to keep in mind as you’re putting these together and considering the completion time of your code.

Switch ('c') {
    'a' {'A'; break}; 'b' {'B'; break}; 'c' {'C'; break}
    'd' {'D'; break}; 'e' {'E'; break}; 'f' {'F'; break}
    'g' {'G'; break}; 'h' {'H'; break}; 'i' {'I'; break}
    'j' {'J'; break}; 'k' {'K'; break}; 'l' {'L'; break}
    'm' {'M'; break}; 'n' {'N'; break}; 'o' {'O'; break}
    'p' {'P'; break}; 'q' {'Q'; break}; 'r' {'R'; break}
    's' {'S'; break}; 't' {'T'; break}; 'u' {'U'; break}
    'v' {'V'; break}; 'w' {'W'; break}; 'x' {'X'; break}
    'y' {'Y'; break}; 'z' {'Z'}
}

C

Instead of putting the true test-value in the parenthesis, we’ll use a variable in the next example. Additionally, we’ll take a look at the Switch’s wildcard parameter. In this example, we’re looking to match multiple conditions. Read it over, and we’ll run through the logic just below the example.

$Building = 'A-Center'

Switch -Wildcard ($Building) {
    'A*' {'Building: A'}
    'B*' {'Building: B'}
    'C*' {'Building: C'}
    'D*' {'Building: D'}
    '*North' {'Location: North'}
    '*South' {'Location: South'}
    '*Center' {'Location: Center'}
    '*East' {'Location: East'}
}

Building: A
Location: Center

The first four conditions, A*, B*, C*, and D*, are in place to match the beginning of the string that was assigned to the Building variable. The first condition, A*, is a match. The last four conditions in the Switch are in place to match the end of the string. Of those, the ‘*Center’ condition is a match. Like it does in other places, the asterisk is a wildcard character; it stands in, for one or more characters.

Here’s the same example, except that we’re outputting the appropriate actions to a variable, instead of writing them to the host. See if you can follow it. Notice that += assignment operators used in the last four conditions. This appends the value to the already existing value assigned to the Location variable.

$Building = 'A-Center'

Switch -Wildcard ($Building) {
    'A*' {$Location = 'Building: A'}
    'B*' {$Location = 'Building: B'}
    'C*' {$Location = 'Building: C'}
    'D*' {$Location = 'Building: D'}
    '*North' {$Location += ', Location: North'}
    '*South' {$Location += ', Location: South'}
    '*Center' {$Location += ', Location: Center'}
    '*East' {$Location += ', Location: East'}
}

$Location

Building: A, Location: Center

There’s still more to cover. We’ll be back with a fourth installment of the Switch language construct next week.