Tag Archives: PSMonday

PSMonday #8: Monday, June 20, 2016

Topic: Less Used Variable Properties

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.

When someone sets, or assigns, a variable in Windows PowerShell, we typically expect it to look a certain way, as is demonstrated below. This example also shows how we typically return a variable’s value, after it’s been assigned.

$String = 'Welcome back to Monday.' # Assign a value to variable.
$String # Return a variable’s value.

Welcome back to Monday.

This assigns, or sets, the variable named string, the value of ‘Welcome back to Monday.’ Straightforward, right? Well, this isn’t the only way to assign a variable in PowerShell. There’s a more formal process that offers a few extra options. When we use the *-Variable cmdlets, we don’t use the dollar sign ($). The dollar sign is only used to indicate to the PowerShell parser that what follows it, will be a variable name. The difference here is that these variable cmdlets already know you’re providing a variable name.

New-Variable -Name String2 -Value 'Come on, Friday.'
Get-Variable -Name String2

Name                           Value
----                           -----
String2                        Come on, Friday.

If you choose to use the Get-Variable cmdlet to return just the value, you can use the -ValueOnly parameter, dotted-notation, or Select-Object’s -ExpandProperty parameter. In older versions of PowerShell, dotted-notation may not be an option.

Get-Variable -Name String2 -ValueOnly
(Get-Variable -Name String2).Value
Get-Variable -Name String2 | Select-Object -ExpandProperty Value

Come on, Friday.
Come on, Friday.
Come on, Friday.

I’m not here to suggest variables should always be created with New-Variable, that values should always be returned with Get-Variable, that variables should always be updated with Set-Variable, or even that we should always clear or remove variables with Clear-Variable and Remove-Variable, respectively. What I’m out to do, is tell you about a couple extra properties that are attached to our variables, that you might not know about, and how we might use them.

Let’s modify the command we used to return the value of our $String2 variable, so we return all the properties. Keep in mind, that we can do the same thing with our $String variable that was created without the New-Variable cmdlet.

Get-Variable -Name String2 | Select-Object *

Name        : String2
Description :
Value       : Come on Friday.
Visibility  : Public
Module      :
ModuleName  :
Options     : None
Attributes  : {}

Notice that we have a Description property and an Options property. The Description property is another way to provide additional meaning to a variable. While you should strive to name your variables in a way that describes their contents, if you’re feeling up to it, you can add additional information about the variable in this property.

Set-Variable -Name String2 -Description 'Demo purposes only'
(Get-Variable -Name String2).Description

Demo purposes only

Let’s talk about the Options property next week, as it’s a bit more useful.

PSMonday #7: Monday, June 13, 2016

Topic: Test-NetConnection

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.

Let’s spend a small part of this Monday morning learning about the Test-NetConnection cmdlet — a potential, telnet replacement. This cmdlet was introduced in PowerShell 4.0 which shipped “in box” with Windows 8.1 and Server 2012 R2.

Test-NetConnection returns a connectivity test to a remote computer. When the cmdlet is entered without a specific computer in which to test against, it will use internetbeacon.msedge.net, a domain owned by the Microsoft Corporation.

Test-NetConnection

ComputerName           : internetbeacon.msedge.net
RemoteAddress          : 13.107.4.52
InterfaceAlias         : Ethernet
SourceAddress          : 10.10.10.50
PingSucceeded          : True
PingReplyDetails (RTT) : 38 ms

This can be helpful, and provides proof of Internet connectivity, but often you’ll want to test a connection closer to the computer that initiated the test. In the case where you want to check a computer in a data center, or only a room away, you can use the -ComputerName parameter and provide a computer name as the parameter value, such as DC01 in this example.

Test-NetConnection -ComputerName DC01

ComputerName           : DC01
RemoteAddress          : 10.10.20.2
InterfaceAlias         : Ethernet
SourceAddress          : 10.10.10.50
PingSucceeded          : True
PingReplyDetails (RTT) : 39 ms

There’s a port parameter that can be used, that will allow you to test against a specific port on the remote computer.

Test-NetConnection -ComputerName DC01 -Port 5985

ComputerName           : DC01
RemoteAddress          : 10.10.10.2
RemotePort             : 5985
InterfaceAlias         : Ethernet
SourceAddress          : 10.10.10.50
PingSucceeded          : True
PingReplyDetails (RTT) : 42 ms
TcpTestSucceeded       : True

If you don’t know the port number, you may be able to use the -CommonTCPPort parameter and supply one of the accepted parameter values. There’s directions at the bottom of today’s PSMonday on how to view the help for this cmdlet, that indicate the accepted values. In this next example, we use RDP as the parameter value for this -CommonTCPPort parameter.

Test-NetConnection -ComputerName DC01 -CommonTCPPort RDP

ComputerName           : DC01
RemoteAddress          : 10.10.10.2
RemotePort             : 3389
InterfaceAlias         : Ethernet
SourceAddress          : 10.10.10.50
PingSucceeded          : True
PingReplyDetails (RTT) : 45 ms
TcpTestSucceeded       : True

There’s also an -InformationLevel parameter that will allow you to specify that you want detailed information returned, or in the case of the example below, only want a Boolean (true or false), value returned.

Test-NetConnection -ComputerName DC01 -CommonTCPPort HTTP -InformationLevel Quiet

False

There are more features to Test-NetConnection, to include a -TraceRoute and a -Hops parameter. If you’re interested in learning more about those, or want to read the full help — much of which you already know, now — enter one of the next two commands.

Get-Help -Name Test-NetConnection -Full
Get-Help -Name Test-NetConnection -ShowWindow

Next time you need to telnet from one host to another, try Test-NetConnection instead of telnet, and see if it isn’t a little more helpful.

PSMonday #6: Monday, June 6, 2016

Topic: Splatting and Hash Tables Continued

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.

So, back to splatting: If you ever have a parameter that doesn’t need an assigned value, where the value is equal to true if the parameter is included, and false if it’s not — a switch parameter — then use $true or $false as the parameter value in the hash table. You can see an example of this below. Notice that in the example one of the parameter values wasn’t hardcoded, and instead was assigned using the value from another variable. Doing this isn’t always necessary, but it’s being shown, as an example for a time when it may be needed.

$Command = 'Get-ADUser'
$Params = @{
    Name = $Command
    ShowWindow = $true
}

Get-Help @Params

It should be said, that if you don’t include a switch parameter in the hash table, that it won’t be included when the cmdlet is run, and will therefore be false by default.

Let’s splat Send-MailMessage. This command, and its need for so many parameters and parameter values, makes it a great candidate for splatting, unlike the above Get-Help command where there was only two included parameters.

$MailParams = @{
    From = 'noreply@mydomain.domain.com'
    To = 'tommymaynard@mydomain.domain.com'
    Subject = 'Using Send-MailMessage and Splatting'
    Body = "This email sent from $env:USERNAME."
    SmtpServer = 'smtp.mydomain.domain.edu'
}

Send-MailMessage @MailParams

Bonus: If you have more parameters to add to a command, and they’re not included in the hash table (for whatever reason), you can still add them to the command.

Send-MailMessage @MailParams -Attachments 'C:\file.txt'

Second Bonus: What could be done instead of adding a separate parameter and parameter value to the command, as we saw in the above Bonus section, is adding another key-value pair to our hash table using the .Add() method.

$MailParams.Add('Attachments','C:\File.txt')

$MailParams

Name              Value
----              -----
Attachments       C:\File.txt
SmtpServer        smtp.mydomain.domain.com
Subject           Using Send-MailMessage and Splatting
Body              This email sent from tommymaynard.
From              noreply@mydomain.domain.com
To                tommymaynard@mydomain.domain.com

Send-MailMessage @MailParams

That’s it. Enjoy your Monday.

PSMonday #5: Monday, May 30, 2016

Topic: Splatting and Hash Tables

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.

There are a couple things in Windows PowerShell that have a strange name. One of them, is splatting.

Consider one of those cmdlets that requires several parameters and parameter values. The below command is an older, modified command that was used to create a PowerShell Web Access authorization rule. This command, is likely going to take up some space and either wrap in the console, or add the need to scroll horizontally in the ISE.

# This example is a lengthy, single command.

Add-PswaAuthorizationRule -RuleName SharePoint-AppAdmins-Rule -ComputerName 'SPCA01' -UserGroupName MYDOMAIN\SP-AppAdmins -ConfigurationName Tools.SharePoint

The length of this command makes it difficult to read and comprehend. Some might be inclined to use the backtick (`) as a line continuation character to help make it more readable.

# This example uses backticks as line continuation characters.

Add-PswaAuthorizationRule `
-RuleName SharePoint-AppAdmins-Rule `
-ComputerName 'SPCA01' `
-UserGroupName MYDOMAIN\SP-AppAdmins `
-ConfigurationName Tools.SharePoint

This option helps some, but I’d recommend not using the backtick as a line continuation character in about 99% of instances. It’s tiny, it’s difficult to see, and if there’s a space after it, the command will throw an error.

Back to splatting. When you splat your parameters and parameter values, you first create a hash table, as signified by @{}. For those that may not know, a hash table contains key-value pairs. The first key in the below example, is RuleName. The associated, first value is ‘SharePoint-AppAdmins-Rule’. Hash tables are also called dictionary objects, or more often, associative arrays. Here’s an example of creating and storing a hash table in a variable with the same parameters and parameter values used in the above examples.

$Parameters = @{
    RuleName = 'SharePoint-AppAdmins-Rule'
    ComputerName = 'SPCA01'
    UserGroupName = 'MYDOMAIN\SP-AppAdmins'
    ConfigurationName = 'Tools.SharePoint'
}

Now, that’s easy on the eyes. Enter the variable name to see the key-value pairs stored in the hash table.

$Parameters

Name                           Value
----                           -----
RuleName                       SharePoint-AppAdmins-Rule
ComputerName                   SPCA01
UserGroupName                  MYDOMAIN\SP-AppAdmins
ConfigurationName              Tools.SharePoint

Now when you run the command, you enter the cmdlet name, the @ symbol, and the name used for the variable (without the dollar sign), as seen in the below example.

Add-PswaAuthorizationRule @Parameters

Now, when this command is run, it will include all the parameters and parameter values defined in our hash table. That’s it for this week. We’ll pick up next week and talk a little more about splatting.

PSMonday #4: Monday, May 23, 2016

Topic: Add and Concatenate Numbers and Strings

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 last week’s PSMonday we determined that numbers can be strings, but that when they are, they lose their numeric properties. As strings, they don’t and won’t act like numbers anymore. For instance, if you “add” the string ‘5’ plus the string ‘5’ you’re not going to get 10. As the plus sign is also a concatenation operator, you end up with the string value of ’55’.

'5' + '5'

55

If you were working with numeric values, such as 5 + 5 — notice there’s no quotes around those digits — then you would get the numeric result of 10.

5 + 5

10

Now that we know what happens when we concatenate two strings and add two numbers, you might wonder what happens when we do this with a string, and a number.

Here’s the key: The object on the left decides what happens. In the first below example, the numeric value on the left coerces the string value on the right into becoming a number, and then the numbers are added. In the second example, we see the opposite. The string value on the left coerces the number on the right into being a string, and then the strings are concatenated.

5 + '5'

10

'5' + 5

55

Expect this to fail at times. In the next example, the number on the left cannot coerce the string value “string” into becoming a numeric value — it’s not possible — and therefore it fails.

5 + 'string'

Cannot convert value "string" to type "System.Int32". Error: "Input string was not in a correct format."

Had this been written in reverse, as it is below, it would work and the result would be ‘string5’. This is because the numeric value 5 can become the string value ‘5’, as we saw earlier.

'string' + 5

string5

Short and sweet today; thanks for reading this PSMonday.

PSMonday #3: Monday, May 16, 2016

Topic: Quotes and Strings, and Their Rules

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.

Today, I’d like to share how to handle quotes in a string. A string is any group of alphanumeric characters to include any punctuation. Think of a string as a sentence, or a word. A string, at its smallest component, can be a single letter, a number, or as mentioned, punctuation. Yes, numbers can be strings too, although they lose their numeric properties.

It is recommended to always use single quotes to encapsulate a string, unless there’s a need for double quotes (they have a special purpose). This is considered best practice by the PowerShell community. The first example string has no internal, interruptive punctuation, such as another single quote, or apostrophe.

$String = 'A string without any quotes.'
$String

A string without any quotes.

The next example string uses internal, double quotes. They are non-interruptive in this instance, because the string begins and ends with single quotes.

$String = 'A string with "double" quotes.'
$String

A string with "double" quotes.

This next example includes both single and double quotes inside a string, that begins and ends with single quotes. Notice that to do this, we needed to put two side-by-side single quotes, around the word single.

$String = 'A string with ''single'' and "double" quotes.'
$String

A string with 'single' and "double" quotes.

One of the things that you might expect to work, is escaping the single quotes instead of using side-by-side single quotes. This doesn’t work.

$String = 'This is a string with `'single`' and "double" quotes.'

At line:1 char:36
+ $String = 'This is a string with `'single`' and "double" quotes.'
+                                    ~~~~~~~~
Unexpected token 'single`'' in expression or statement.

Although I said to use single quotes to encapsulate a string, you can use double quotes if you have internal single quotes, or apostrophes, and you don’t want to use side-by-side single quotes.

$String = "I'm only using 'single' quotes in this string."
$String

I'm only using 'single' quotes in this string.

The final reason you might use double quotes is when you want to expand, or display, the value stored in a variable(s) inside your string. You can’t do this with single quotes. Notice in the below example that we’re using side-by-side double quotes in this string.

$Word1 = 'string'
$Word2 = 'quotes'
$String = "This is a $Word1 with 'single' and ""double"" $Word2."
$String

This is a string with 'single' and "double" quotes.

Bonus: Back to escaping, you can escape double quotes, so the example above could have been written like the example below, and therefore, not required using side-by-side double quotes. Don’t forget about apostrophes in your contractions (I’m, don’t, aren’t, etc.). You’ll need to determine a way around those as you create strings where they’re included.

$String = "This is a $Word1 with 'single' and `"double`" $Word2."
$String

This is a string with 'single' and "double" quotes.

And with that, the third PowerShell Monday is complete. As mentioned previously, please let me know if there’s something you’d like to see discussed.

PSMonday #2: Monday, May 9, 2016

Topic: Best Way to Filter the Results of Your Commands

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.

Today we’re going to discuss the best way to filter the results of our commands. These first two commands return the same results — the services on the local computer that begin with the letter L. Let’s discuss why one is better than the other, right after we take a look at the commands.

Get-Service | Where-Object Name -like L*

# And

Get-Service -Name L*

While piping the results of one command to another is beneficial in Windows PowerShell, it’s not always the best idea. If a cmdlet has a way to filter your results without the need to pipe it to a filtering cmdlet, such as Where-Object, then use it. The reason this is faster is because in the first above example we return ALL the services first and then filter them one by one. In the second example, we filter immediately, which means we never stop to consider services that start with any other letter than L. You might someday hear this called the filter left rule. The idea is to do as much filtering as close to the left of your commands as possible. You might also here it as filter left, format right. This is to say that formatting cmdlets (Format-Table, Format-List, etc.) should be as far to the right of a command(s) as possible (typically the last cmdlet in a command that includes piping).

Here’s an example from Active Directory (AD). In the first command we return EVERY AD user object and then filter them, whereas in the second command we filter immediately and only process the users we want to return. In the case of AD, it’s not only faster, but it’s going to be less resource intensive than peering at every AD user object in the entire domain, to only return what might be a handful of users.

Get-ADUser -Filter * | Where-Object Surname -eq 'Smith'

# And

Get-ADUser -Filter {Surname -eq 'Smith'}

I ran the two above commands through the Measure-Command cmdlet in order to measure their execution times. I did this around 10 p.m. Saturday evening using my last name. The first command, that checked every AD user object, took 6 1/2 minutes to complete. The second command took an average of 30 milliseconds. That’s a big difference.

Bonus: Here’s how to determine which cmdlets have a specific parameter. In this case, we’re checking for cmdlets that include a -Filter parameter. The below image only shows the first nine cmdlets of the sixty found on my computer that include this parameter. Remember, however, that in the case of the Get-Service cmdlet, that we didn’t filter with a -Filter parameter. In that instance, we used the -Name parameter, as it accepted wildcards. Use Get-Help to determine if a cmdlet’s parameters accept wildcards, or not.

Get-Command -ParameterName CommandType

CommandType     Name                                               ModuleName
-----------     ----                                               ----------
Cmdlet          Add-Content                                        Microsoft.PowerShell.Management
Cmdlet          Clear-Content                                      Microsoft.PowerShell.Management
Cmdlet          Clear-Item                                         Microsoft.PowerShell.Management
Cmdlet          Clear-ItemProperty                                 Microsoft.PowerShell.Management
Cmdlet          Copy-Item                                          Microsoft.PowerShell.Management
Cmdlet          Copy-ItemProperty                                  Microsoft.PowerShell.Management
Cmdlet          Get-ADAuthenticationPolicy                         ActiveDirectory
Cmdlet          Get-ADAuthenticationPolicySilo                     ActiveDirectory
Cmdlet          Get-ADCentralAccessPolicy                          ActiveDirectory

That’s all. We’ll be back at it next Monday.

PSMonday #1: Monday, May 2, 2016

Topic: Setting Multiple Variables at the Same Time

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.

Welcome to the first PowerShell Monday.

Let’s get started: The first example shows one way to set, or assign, a value to a variable in Windows PowerShell. In this example, $p is assigned the string value ‘Welcome to Monday’.

$p = 'Welcome to Monday.'

Knowing that, what do you think this command accomplishes?

$a = $b = $c = 'string'

# Answer further below…








# Keep going…








# Keep going…








# Keep going…








After running that command, here are the values stored in $a, $b, and $c.

# The command was $a = $b = $c = 'string'.
$a
$b
$c

string
string
string

A command such as this, although not often seen, sets all three variables to the same value. Knowing this in an option, allows us to initialize a group of variables to the same value, at the same time. While you can do this in three separate commands, as the next two examples show, you can complete the same thing, as part of a single command.

# The line break is a command separator in PowerShell.
$x = 'string'
$y = 'string'
$z = 'string'
# The semicolon is a command separator, too.
$x = 'string'; $y = 'string'; $z = 'string'

Bonus: What do you think this command does?

$m,$n,$o = 'string'

You probably won’t ever see this command — I haven’t — but why not know what it does. In this example, only $m is assigned the value of ‘string’. The other two — $n and $o, in this example — lose any value they may have been storing. Again, I haven’t seen this, and I wouldn’t recommend you use it. I suspect that it would end up being confusing, compared to the traditional methods of assigning and removing values from variables. I said it was a bonus; I didn’t say it was a useful.

Second Bonus: What about this command; what do you think happens here?

$e,$f,$g = 'Monday','Tuesday','Wednesday'

I’ve never seen this command used either, but I can see how this one might be useful to use, without too much confusion. I still won’t recommend it, though. In this example, we end up assigning ‘Monday’ to $e, ‘Tuesday’ to $f, and ‘Wednesday’ to $g. If we had a fourth variable, such as $h, and it had a value in it, the value would be removed, such as we saw in the first bonus. This is of course, unless there was another value after ‘Wednesday’.

That’s it for the first PSMonday. Hope you’ve learned something new, and we’ll do this again next week.

PowerShell Monday Table of Contents

I’m trying something new at work dubbed PSMonday, as in—and, I hope you could’ve guessed this—PowerShell Monday. I’m writing up 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 are consistently learning something new about Windows PowerShell. This includes both my team, and our Operations Team (Edit: And, now our VMware Team, too. Edit2: Our Windows DBA is reading along, as well.).

Well, I thought about it over the weekend, and I can’t figure out why I wouldn’t also include the lesson right here. If you’re into PowerShell too, then I would encourage you to do a PSMonday at your place of work, as well. Help people help themselves. These posts are sorted beginning with the oldest PSMonday at the top. Scroll to the bottom to locate and read the newest PowerShell Monday, and check out the ones in between.

PSMonday #1: Monday, May 2, 2016
Topic: Setting Multiple Variables at the Same Time

PSMonday #2: Monday, May 9, 2016
Topic: Best Way to Filter the Results of Your Commands

PSMonday #3: Monday, May 16, 2016
Topic: Quotes and Strings, and Their Rules

PSMonday #4: Monday, May 23, 2016
Topic: Add and Concatenate Numbers and Strings

PSMonday #5: Monday, May 30, 2016
Topic: Splatting and Hash Tables

PSMonday #6: Monday, June 6, 2016
Topic: Splatting and Hash Tables Continued

PSMonday #7: Monday, June 13, 2016
Topic: Test-NetConnection

PSMonday #8: Monday, June 20, 2016
Topic: Less Used Variable Properties

PSMonday #9: Monday, June 27, 2016
Topic: Less Used Variable Properties Continued I

PSMonday #10: Monday, July 4, 2016
Topic: Less Used Variable Properties Continued II

PSMonday #11: Monday, July 11, 2016
Topic: PowerShell Remoting

PSMonday #12: Monday, July 18, 2016
Topic: PowerShell Remoting Continued

PSMonday #13: Monday, July 25, 2016
Topic: PowerShell Remoting Continued II

PSMonday #14: Monday, August 1, 2016
Topic: PowerShell Remoting Continued III

PSMonday #15: Monday, August 8, 2016
Topic: PowerShell Remoting Continued IV

PSMonday #16: Monday, August 15, 2016
Topic: PowerShell Remoting Continued V

PSMonday #17: Monday, August 22, 2016
Topic: PowerShell Remoting Continued VI

PSMonday #18: Monday, August 29, 2016
Topic: Get-Member

PSMonday #19: Monday, September 5, 2016
Topic: Get-Member Continued

PSMonday #20: Monday, September 12, 2016
Topic: Get-Member Continued II

PSMonday #21: Monday, September 19, 2016
Topic: Get-Member Continued III (and Arrays)

PSMonday #22: Monday, September 26, 2016
Topic: Get-Member Continued IV

PSMonday #23: October 3, 2016
Topic: Commands, Cmdlets, and Functions

PSMonday #24: October 10, 2016
Topic: $PSDefaultParameterValues

PSMonday #25: October 17, 2016
Topic: $PSDefaultParameterValues II

PSMonday #26: October 24, 2016
Topic: PowerShell’s Importance

PSMonday #27: October 31, 2016
Topic: Introduction to the Language Constructs

PSMonday #28: November 7, 2016
Topic: If, If-Else, If-ElseIf

PSMonday #29: November 14, 2016
Topic: If, If-Else, If-Else II

PSMonday #30: November 21, 2016
Topic: If, If-Else, If-Else III

PSMonday #31: November 28, 2016
Topic: Switch Statement

PSMonday #32: December 5, 2016
Topic: Switch Statement II

PSMonday #33: December 12, 2016
Topic: Switch Statement III

PSMonday #34: December 19, 2016
Topic: Switch Statement IV

PSMonday #35: December 26, 2016
Topic: Foreach

PSMonday #36: January 2, 2017
Topic: Foreach II

PSMonday #37: January 9, 2017
Topic: ForEach-Object

PSMonday #38: January 16, 2017
Topic: ForEach-Object II

PSMonday #39: January 23, 2017
Topic: For

PSMonday #40: January 30, 2017
Topic: Do-While

PSMonday #41: February 6, 2017
Topic: Do-Until

PSMonday #42: February 13, 2017
Topic: While

PSMonday #43: February 20, 2017
Topic: Reusable Code I

PSMonday #44: February 27, 2017
Topic: Reusable Code II

PSMonday #45: March 6, 2017
Topic: Reusable Code III

PSMonday #46: March 13, 2017
Topic: Reusable Code IV

PSMonday #47: March 20, 2017
Topic: Reusable Code V

PSMonday #48: March 27, 2017
The (Online) End of PowerShell Monday