Monthly Archives: May 2016

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.

Linux Prompt on Windows – Part II

A while ago, I wrote myself a new prompt function and shared it here. Well, I’m here to report that I’m still using it in both the ConsoleHost and the ISE. Here’s an image from the first post that shows what it looks like.

duplicate-the-linux-prompt01

The thing about this prompt function, is that it also modified the WindowTitle to reflect the exact same information — the user, the computer, the location on the current drive, and whether or not you’re admin (# = admin vs. ~ = not admin). I love that too, but there’s turned out to be one little inconvenience. Besides the minutely different icons, I can’t quickly tell if I’m about to open the ISE or ConsoleHost from its taskbar icon. Therefore, I modified the prompt function every so slightly to indicate which host is which. Take a look.

an-addition-to-my-linux-powershell-prompt01

Now I can better determine which host I want — CH for ConsoleHost and ISE for, well, the ISE — before I bring it back to the front. As expected, it only took a minor change. I added a switch statement that evaluated the value in $Host.Name. Based on its value, it populated a variable called $HostName that’s used as a part of the assigned valued in the WindowTitle.

Function Prompt {
	(Get-PSProvider -PSProvider FileSystem).Home = $env:USERPROFILE

	# Determine if Admin and set Symbol variable.
	If ([bool](([System.Security.Principal.WindowsIdentity]::GetCurrent()).Groups -match 'S-1-5-32-544')) {
		$Symbol = '#'
	} Else {
		$Symbol = '$'
	}
	 
	# Write Path to Location Variable as /.../...
	If ($PWD.Path -eq $env:USERPROFILE) {
		$Location = '~'
	} ElseIf ($PWD.Path -like "*$env:USERPROFILE*") {
		$Location = $PWD.Path -replace ($env:USERPROFILE -replace '\\','\\'),'~' -replace '\\','/'
	} Else {
		$Location = "$(($PWD.Path -replace '\\','/' -split ':')[-1])"
	}

	# Determine Host for WindowTitle.
	Switch ($Host.Name) {
		'ConsoleHost' {$HostName = 'CH '; break}
		'Windows PowerShell ISE Host' {$HostName = 'ISE'; break}
		default {}
	}

	# Create and write Prompt; Write WindowTitle.
	$Prompt = "$($env:USERNAME.ToLower())@$($env:COMPUTERNAME.ToLower()) $Location $Symbol "
	$Host.UI.RawUI.WindowTitle = "$HostName`: $Prompt"
	$Prompt
}

Update: After a week or so, I updated the function again. I couldn’t stand the capital CH and ISE. So, that’s fixed: It’s ch and ise, now. There may come another change, too. When I’m not on the C:\ drive, I’d like to include an indication in the WindowTitle. Here’s the update.

Windows PowerShell Constrained Endpoints, Proxy Functions, and Just Enough Administration

I had a recent request for some information in regard to constrained endpoints. There was a lengthy article posted in a PowerShell.org TechLetter earlier this year that I authored (it actually won me a free 4-day pass to the PowerShell + DevOps Global Summit 2016). As of now, those don’t appear to be back online, since the recent redesign and changes over there.

Therefore, I’ve opted to post the paper here. Keep in mind, as you read this, that we should be moving away from constrained endpoints of the past and toward JEA endpoints of the future. Realistically though, I’m pretty sure those constrained endpoint cmdlets of the past, are the ones of the future, with some new additions. I should probably go get my hands dirty. Enjoy!

Note: Throughout the course of this previously written paper, I used the term proxy function rather loosely. I’ve done some thinking since then, and no longer use it that way. Going forward, or if I were to rewrite this paper, I wouldn’t use the term proxy function. Instead, I would refer to the included functions as wrapper functions, as they wrap other commands, and didn’t have anything to do with obtaining the cmdlet metadata and using that to write a function. If they had, then they’d be proxy functions.

Windows PowerShell Constrained Endpoints, Proxy Functions, and Just Enough Administration (3488 downloads )

Creating Multiple Credential Objects Part II

Download the updated function here: https://gist.github.com/tommymaynard/98031ccd5de67005bf3063db06a33851

Back in January 2015, I wrote a post and uploaded an advanced function to the TechNet Gallery that allows a user to create multiple credential objects. Edit: The TechNet Gallery no longer hosts scripts/modules, so use the GitHub Gist at the top and bottom of this page. The multiple part is up to the user, such as they might enter a command as in the below example. Due to the -Set 2 parameter and parameter value, they would get prompted twice, to enter a username and password combination. When the function was completed, they would have two credential objects, with the first stored in $CredSet1 and the second stored in $CredSet2.

New-TMMultiCred -Set 2

I had always wanted to make a couple of changes to the advanced function, and so I have. Now the function includes a -NoGui parameter, that will not require the username and password be entered into the Get-Credential GUI, and can instead be entered directly into the console. I should mention that if this was run in the ISE, the password would actually invoke a small GUI for the password, as is standard when using Read-Host‘s -AsSecureString parameter in that host.

The other addition I wanted to add is that the advanced function produces objects, instead of using the Write-Output cmdlet to display information. Now, instead of the function writing this:

SUCCESS: Credential Set 1 stored in $CredSet1
SUCCESS: Credential Set 2 stored in $CredSet2

the function writes this:

CredSet             Variable            UserName                                 Password
-------             --------            --------                                 --------
1                   $Credset1           mydomain\admin       System.Security.SecureString
2                   $Credset2           user1                System.Security.SecureString

Neat, right? So download it and try it out. I think it was a decent addition to an already helpful advanced function.

Download the updated function here: https://gist.github.com/tommymaynard/98031ccd5de67005bf3063db06a33851

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.

AWS Stop-EC2Instance Needs Complimentary Cmdlet

Well, it’s time to try this again: Can a Tweet get another change to the AWSPowerShell module? Maybe you’ve read a recent post about an inconsistent parameter name between the same parameter, in two corresponding cmdlets. One tweet later and that was on its way to being fixed. You can read about that here: http://tommymaynard.com/twitter-reply-hashtag-aws-tweet-prompts-fix-to-awspowershell-module-2016.

I get that a tweet probably isn’t the preferred method of reporting problems, but it worked before, so why shouldn’t it again? That said, if there is a preferred method, then I’d be happy to use that, although it doesn’t make for as good a story.

So, here’s where we need a fix. The Stop-EC2Instance cmdlet includes a Terminate switch parameter that indicates it will terminate the instance (think, remove) in addition to stopping it. It works; it really does terminate the instance. The problem here is that the help file indicates it will prompt the user for confirmation unless the Force parameter is also included. Nope; it doesn’t prompt. Not for me at least. It does terminate the instance, however, and it does so with no questions asked. It didn’t get me, but it might ruin someone’s day someday.

I didn’t try it, but it seems that there’s some built-in protection, although it’s not the default.

aws-stop-ec2instance-needs-complimentary-cmdlet01

So you can see it yourself, here are two PowerShell commands I ran against two different EC2 instances. In the first command, I simply stop an EC2 instance. In the second, I added the Terminate switch. As I mentioned, it works, but there wasn’t a confirmation prompt. This was tested on AWS Tools for Windows PowerShell 3.1.66.0 and the newest version as of this writing, 3.1.71.0.

aws-stop-ec2instance-needs-complimentary-cmdlet02

aws-stop-ec2instance-needs-complimentary-cmdlet03

My suggestion to resolve this problem is to remove the Terminate switch from the Stop-EC2Instance cmdlet, and make a Remove-EC2Instance cmdlet. Maybe alias it with Terminate-EC2Instance, as Terminate isn’t an approved verb. In fact, when I first wanted to remove an EC2 instance, I started by hunting for a Remove-EC2Instance cmdlet. Tracking down the Terminate switch of Stop-EC2Instance was the last place I would’ve looked. It seems to go against all PowerShell conventions. Does Stop-Transcript have an option to remove a transcript as part of its usage? Does Stop-VM in Hyper-V delete the VM? Does Stop-Cluster include a way to delete the cluster? No. Terminating an instance shouldn’t be a part of stopping an instance unless Stop-EC2Instance can be piped to Remove-EC2Instance. Think about the safety that a separate cmdlet would provide (and it’s not like the AWS Tools team is shy about adding new cmdlets).

There are a couple of cmdlets out there that can be used to get the metadata from a compiled PowerShell cmdlet. We use it as a part of writing proxy functions. By using this, I was able to determine the reason why it doesn’t prompt. The problem, as best I can tell, is that Stop-EC2Instance‘s ConfirmImpact CmdletBinding attribute is set to Medium and the default value of the $ConfirmPreference variable is High.

aws-stop-ec2instance-needs-complimentary-cmdlet04

This means that no matter how the Stop-EC2Instance cmdlet is run, it’s never going to prompt for confirmation to terminate, unless someone has modified their $ConfirmPreference value to Medium, and that’s not likely at all. Since a cmdlet, or advanced function, can’t have more than one ConfirmImpact argument, we need the terminate functionality removed from Stop-EC2Instance and the development of a Remove-EC2Instance cmdlet. For comparison, here’s the CmdletBinding attribute for the Remove-ADGroupMembership Active Directory cmdlet. This one always prompts unless we include -Confirm:$false.

aws-stop-ec2instance-needs-complimentary-cmdlet05

I get this fix is much more involved than the last one I brought up (changing the name of a parameter), and would require more work. Additionally, it’s probably one of those things that have to be discussed among the AWS Tools team members and management. Before I close, I should make sure everyone knows that AWS is still new to me, and as such, there may be things that weren’t considered, or known, when this post was written.

Thanks for reading, and enjoy the upcoming weekend.

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.

Write-Output Gets Foreground and Background Colors and More

Every once in a while a forum post comes along that really captures my interest. Take this one for instance.

In this post, the creator wanted to build out a start up menu in the ConsoleHost that has a solid white line, another white line below that, with the words “PowerShell Project 1” in it, and a final white line beneath that. That might be difficult to imagine, so here’s a visual representation, and then what his/hers looked like. I had recommended to use a here-string to fix the problem, but unfortunately we didn’t have the same results.

write-output-gets-foreground-and-background-colors-and-more01
Note: While you can’t see them, in both this and the below image, there are spaces on the lines above, below, and before and after “PowerShell Project 1.” This is how we can ensure the white rectangle around the text.

write-output-gets-foreground-and-background-colors-and-more02

I can’t say for certain why theirs rendered differently, but I suspect version, or PSReadline, or possibly console font/size. That wasn’t important; what was, was trying to figure out a way around this problematic inconsistency. We have the option to change the background color of the area where we type, and so I wondered if I could temporarily do that inside the ConsoleHost. It turns out I could. With that new piece of knowledge, I set out to write a wrapper function around Write-Output. In my version — Write-TMOutput — it includes -ForegroundColor and -BackgroundColor parameters with an option to horizontally and vertically pad the text (object).

First, here’s a few images to show my new function in action. This first image shows the commands included in the TMOutput module.

write-output-gets-foreground-and-background-colors-and-more03

The next example image shows some basic, Write-Output type usage. One where we pipe to the function, and one where we don’t. Fairly standard.

write-output-gets-foreground-and-background-colors-and-more04

Now, the next example is where this starts to get fun: the incorporation of the -ForegroundColor and -BackgroundColor parameters. Prior to running these commands, and those in the last two examples, I removed the PSReadLine module so the colors would be easier to spot.

write-output-gets-foreground-and-background-colors-and-more05

Next is a demo of two additional parameters: -HorizontalPad and -VerticalPad. These will allow you to add spaces before and after the value supplied to the -InputObject parameter (the text), and add lines above and below the text. This is the part that gets back to the request in the Microsoft Technet forum post. I should mention that my solution in the forum post would be different now that I’ve spend some time writing this function — there are better ways to do things that I hadn’t considered at the time I replied to the post.

write-output-gets-foreground-and-background-colors-and-more06

The next example shows some usage with the Get-ADUser cmdlet. Keep in mind that if you combine this function with other cmdlets, that the -HorizontalPad and -VerticalPad parameters cannot be used. In my mind, they’re just a bonus to the option of using colors with Write-Output. I should mention it now, but this function was intentionally written to only work in the ConsoleHost. Perhaps I’ll add the option of using it in the ISE in the future.

write-output-gets-foreground-and-background-colors-and-more07

I’ve written an additional function that will allow you to quickly see the available colors from which you can choose. It’s called Show-TMOutputColor, and produces the results below. This might come in handy as you’re using the modified Write-Output.

write-output-gets-foreground-and-background-colors-and-more08

Now, on to the module. It’s the first time I’ve done it, but I’ve uploaded this to the PowerShell Gallery. I believe publishing to the PowerShell Gallery was one of my PowerShell New Year’s Resolutions for 2016, so there’s one down! You can use this direct link or, one better, download the module from your console, using this command:

Install-Module -Name TMOutput

Thanks for reading this post. Hopefully these function will be a useful way to get around the need for Write-Host’s foreground and background color options while working in the console. That, and maybe the TechNet thread creator can do whatever they wanted, too.

Hashtag AWS Tweet Prompts Fix to AWSPowerShell Module

I started the Twitter Reply category so I would be able to reply to things I saw on Twitter that needed to be done outside of the 140-character limit. I’ve used it this way a few times, however, today’s usage is a little different. Although it incorporates Twitter and it’s going to take longer than 140 characters, I’m not actually replying to someone so much. Instead, I am bringing up an event that transpired on Twitter.

First, let me begin by saying how impressed I am with at least one of the developers—I’m guessing he’s a developer—working on the AWSPowerShell module. Last Wednesday, I tweeted that I had started and then stopped an EC2 instance using the Start-EC2Instance and Stop-EC2Instance cmdlets. I noticed a naming difference between identical parameters used by these two, complimentary cmdlets, as I mentioned in my Tweet.

Steve Roberts—a complete stranger to me—replies to my tweet as he must follow the #AWS hashtag. The part that sticks out is that he wrote, “…Fixing…,” as if he was going to correct this difference. Hilarious, right?

Cut to just over 24 hours later and it’s fixed. I downloaded the newest version of the module, installed it, and tested it. It was fixed. The complimentary cmdlets now use the same, InstanceId parameter.

Did that really just happen? For all I knew, this Steve guy was messing with me, but no, my Tweet really did initiate a (very minor) fix included in the newest version of the AWSPowerShell module. That’s a first. Well, I’ve found a new problem. Maybe I can get that one fixed, too. I’ll be writing about that in an upcoming post and will link it from here, as soon as it’s complete.

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.