New Stuff: Get-Clipboard And Set-Clipboard – New In PowerShell 5.0

Predictably, there are lots of new cmdlets coming in PowerShell/Windows Management Framework 5.0. Two of them that just came out in build 10105 are the Get-Clipboard and Set-Clipboard cmdlets. The help docs aren’t all written at the time I’m writing this post but I wanted to introduce them and highlight a couple neat use cases I immediately thought of.

New Get-Clipboard and Set-Clipboard cmdlets

New Get-Clipboard and Set-Clipboard cmdlets (click for larger)

Back in the old days of PowerShell 4.0, you had to pipe output to clip.exe or use the PowerShell Community Extensions to interact with your clipboard. Not anymore!

Looking at the Get-Clipboard syntax, it’s quickly apparent that you can do more than just get the clipboard’s text content but let’s start with that anyway. So, what if I go and select some text, right click and copy it. What can I do with the Get-Clipboard cmdlet?

Not exactly mind blowing. Similarly, you can use the Set-Clipboard cmdlet to put text on the clipboard.

I’m probably not blowing your mind with this one either. Where this gets fun is when you consider the possibilities the using the -Format parameter. I can put more than just text on my clipboard, right? Let’s see what I get when I copy three files in my c:\temp directory to my clipboard. If I try to just use Get-Clipboard without any additional parameters or info like I did in the above examples, I won’t get anything returned, but what I can do is this.

Now we’re doing cool things. And what kind of objects are these?

FileInfo! We can do all the same things with this array of files that we would do to the results of a Get-ChildItem command. This means we can go the other way too and use the Set-Clipboard cmdlet to put a bunch of files onto the clipboard.

Note with all of the above examples, you can use the -Append parameter to simply add on to whatever is already on the clipboard.

I won’t cover the other formats (Image and Audio) or the text format types because you need something to discover for yourself. The last thing I’ll point out is that you can easily clear the clipboard, too.

I’m not going to cover every new cmdlet that comes out with PowerShell 5.0 but this one is very accessible and I think I’ll be able to use it all over the place.


Quick Tip: Search Remote Computer Certificate Store

It’s really easy to search your local certificate store using PowerShell. You simply run a command like this.

The above command will recursively look through all the certs in the local machine store and return the ones that have the word “Interesting” in the subject. Not exactly re-inventing the wheel here.

There’s not a ton of great options for snooping through the certificate store of remote computers, though. The solution I chose to get around this is dead simple. I used the Invoke-Command cmdlet to scan the certificate store of a remote computer. It’s so easy that it almost feels like cheating.



Invitation: MVP Virtual Conference

This is a canned post provided by the Microsoft MVP program. I’m sharing it because I think it’s going to be a valuable event that readers of this blog could get a lot out of. I’m definitely going to be there and I’m really looking forward to it. Take a look and see if it’s something you’re interested in.



Register to attend the Microsoft MVP Virtual Conference

I wanted to let you know about a great free event that Microsoft and the MVPs are putting on, May 14th & 15th.  Join Microsoft MVPs from the Americas’ region as they share their knowledge and real-world expertise during a free event, the MVP Virtual Conference.

The MVP Virtual Conference will showcase 95 sessions of content for IT Pros, Developers and Consumer experts designed to help you navigate life in a mobile-first, cloud-first world.  Microsoft’s Corporate Vice President of Developer Platform, Steve Guggenheimer, will be on hand to deliver the opening Key Note Address.

Why attend MVP V-Conf?  The conference will have 5 tracks, IT Pro English, Dev English, Consumer English, Portuguese mixed sessions & Spanish mixed sessions, there is something for everyone!  Learn from the best and brightest MVPs in the tech world today and develop some great skills!

Be sure to register quickly to hold your spot and tell your friends & colleagues.

The conference will be widely covered on social media, you can join the conversation by following @MVPAward and using the hashtag #MVPvConf.

Register now and feel the power of community!



Quick Tip: Protect Your Active Directory From Finger Slips

Do you ever worry about giving Domain Admin or other Active Directory privileges to people? I do, so I decided to protect some sensitive items in my AD from accidental deletion – or as I like to call it, protecting against finger slips.

3-16-2015 10-47-03 AM

We’re talking about this flag.

I’ve got some OUs that have user and group objects that I would really miss if they were to be accidentally deleted. Furthermore, I would really miss any entire OU if it were to be deleted. I’m not interested in protecting individual computer accounts or user/group accounts in non-sensitive OUs.

Here’s the script I used:

Line 1 defines an array of names of my sensitive OUs. Lines 2 and 3 are basically the same: they get all the AD objects in the sensitive OUs with an ObjectClass of group or user and protect them from accidental deletion. Why do this in two lines? I was getting inconsistent results (computer and other objects were returned) when I tried combining the filter. My AD isn’t that big so this works just fine for me. Line 4 protects all my OUs in my AD from accidental deletion.


Quick Tip: String Manipulation – First Name Last Name to Last Name, First Name

I’ve got kind of a silly post this week. I often get a list of names in the format…

John Doe

Jane Doe

Mike Smith

Mary Smith

… that I actually need to be in the format…

Doe, John; Doe, Jane; Smith, Mike; Smith, Mary

… and sometimes, especially with long lists of names, it’s a pain to do the manipulation in Notepad or Word. So what do you think I did? That’s right, I wrote a PowerShell script to handle it for me. I just throw the list of people into a text file and call up this script.

This isn’t the tidiest script but I break it up into a couple extra parts so it’s easier to edit on the fly. I might comment out the ” | clip.exe ” part of the last line if I don’t want the output on my clipboard.

The first line just gets the content of the text file and the second line initializes the variable $csnames (which stands for [semi]colon separated names). On the third line, I go through every value in the text file and put the part after the first space (the last name), a comma and space, and then the part before the first space (the first name) into the $csnames string. I throw a semicolon on and move to the next one.

This won’t do well with names like “John van Doe” that have multiple spaces. It just happens to suit my needs and might serve as a super simple example to some of you who are trying to wrap your heads around manipulating strings in PowerShell.


Imported PowerShell Sessions ErrorActionPreference Gotcha

I just bumped into something silly that I know I’ll forget about in the future. Using the function in my PowerShell profile to open an Exchange Management shell, I ran the following command as part of a script.

It’s a pretty self-explanatory command. I was trying to detect if a mailbox, in this case “doesntexist”, existed or not. Typically if the mailbox doesn’t exist, the Get-Recipient cmdlet will throw an error. My goal was to catch the error and do something productive with it but the above command doesn’t trigger the Catch block.

No problem, I thought to myself. My ErrorActionPreference is set to Continue by default so I’ll tweak it for this command.

The -ErrorAction Stop part should make the script stop executing on an error and hop into the Catch block. Wrong! The above command throws an error without triggering the Catch block, too.

It turns out I had to edit my $ErrorActionPreference variable to be Stop. Just using the flag in the command doesn’t work. I’ve run into this in other scripts where I import a PSSession, too. Now my command looks something like this.

First, I’m getting the current value of $ErrorActionPreference and storing it. Then I set the ErrorActionPreference to Stop. I run my Get-Recipient command which fails and now instead of getting an error, my Catch block is triggered. Afterwards, I set $ErrorActionPreference back to it’s previous value.

Now, because I’ve written a blog post about this, I’ll never forget again.


Quick Tip: Use PowerShell To Detect If A Location Is A Directory Or A Symlink

In PowerShell, symbolic links (symlinks) appear pretty transparently when you’re simply navigating the file system. If you’re doing other work, though, like changing ACLs, bumping into symlinks can be a pain. Here’s how to tell if a directory in question is a symlink or not.

Consider the following commands.

Here, we’re just running a Get-Item command on two locations, getting the Attributes property and converting to a string. The first item is a symlink and includes “ReparsePoint” in its attributes. The second item is a normal directory and does not include “ReparsePoint”.

So that means we can do something as easy as this.

Easy. If the above values have “ReparsePoint” in them, we know they are a symlink and not just a regular directory. In my case, my script to apply ACLs to a group of directories avoided symlinks with ease.


Bypassing PowerShell Execution Policy

Let me be absolutely clear about this post. I do not in any way encourage or support people who wish to use the below information to circumvent the controls put in place by companies and administrators. This post is strictly for academic purposes and for the sake of sharing information.

PowerShell Execution Policies control whether or not a system may run a PowerShell script based on whether the script is signed or not. See the about_Execution_Policies Technet page for more information if you are unfamiliar with execution policies or how to apply them. Execution policies do not, however, limit a user or service from running commands in a PowerShell shell (PowerShell.exe).

So what if you have an unsigned script you want to run but your execution policy is preventing it? Well, there’s a way to bypass the execution policy. And it’s run from a PowerShell shell.

Administrative users can easily bypass the execution policy with this command.

But what about limited users? Well there’s something for them, too.

That’s right, just one line. No registry hacking, no weird developer program strangeness, just a command that allows a user or service to subvert the execution policy of the machine.

Let’s break down the command. We’re launching PowerShell.exe, not exactly a puzzler. We want it with no profile and we’re telling it to run a command. The trick is that the command we’re running is effectively going to be the script that our execution policy would otherwise block.

The dot is basically an alias for “execute” and in this case, we’re telling it to execute what’s in the proceeding round brackets. The round brackets contain instructions to create a new ScriptBlock out of the contents of the .ps1 file that the execution policy would otherwise prevent from running.

I think it’s clear that this is not really something that Microsoft intends for you to do. Use (or not) wisely at your own discretion.


Find All Certificates Issued Of A Specific Template

As part of another PowerShell script I’m writing, I needed to get an array of all of the certificates issued in my Enterprise PKI environment by a specific Issuing Certificate Authority (CA) that are of a certain Certificate Template.That doesn’t sound like such a tall order. You can launch MMC.exe, add the Certification Authority module, browse the issued certificates and see for yourself the different issued certs and their template.

PowerShell is a bit trickier, though, for a couple reasons. First, you’re going to need a PowerShell module to help you with this task. I really like PSPKI (available on CodePlex). Install that module and run the command to import the module.

The next tricky thing to keep in mind is that your “CertificateTemplate” attribute on each issued cert doesn’t always present itself like you think it should. That’s pretty ambiguous so I’ll explain more.

In the Certificate Authority MMC, most of the certificates you issue should have a value in the Certificate Template column along the lines of Template Name (OID for the template) where the part in brackets is the unique object identifier (OID) for the template. In the MMC, this information is presented pretty consistently. This isn’t really the case for PowerShell.

The following command will get you a list of all the Certificate Templates that have been used to issue certs on your CA as the Certificate Templates are presented in PowerShell.

The first thing we need to do is get the CA since the Get-IssuedRequest cmdlet works with a CA. We get the issued requests (the certificates that have been issued from the CA) while making sure to include the CertificateTemplate property. Then we just select the unique Certificate Templates. Mine returns a mixed list of OIDs and more traditional names – not Name (OID) like we saw in the MMC. Keep this in mind as we continue.

Back on track, where’s my list of certs with a specific template?

With the above information in mind, we’re better armed to get a list of all certs issued by our CA with a specific template. We really only have two steps: 1. Find out how the Certificate Template we’re concerned with is represented in PowerShell and 2. Actually get the list of certs with that template.

Task 1 isn’t so hard. First, go into the Certification Authority MMC and find a cert with the template you are concerned with. Look at the Issued Common Name column and take note of the value in that column. Then in PowerShell, run this command.

Like above, we’re getting the CA we’re concerned with and getting the issued requests. This time, though, we’re not looking to return every cert issued, just the one(s) where the Common Name is the same as the value you saw in the MMC. We also need to make sure to include the CertificateTemplate property because it’s not returned by default. Use -property * to get every property back and take a detailed look at a certificate. There are some neat things you can do.

This will get you back a bit of interesting information about the certificate you identified in the MMC as being of the correct template. Specifically, you can see what the value is under the CertificateTemplate property. Maybe it’s a friendly name, maybe it’s an OID. Either way, that’s the value that PowerShell is using to identify that particular template.

Use the above value for the CertificateTemplate in this command.

We’re getting the CA, getting all the issued certs (including those certs’ CertificateTemplate property) and filtering where the CertificateTemplate property is equal to the one we found in the last command we ran.

There you go! Export that to a CSV, assign it to a variable. The rest is up to you.


Quick Tip: List All SMA Schedules That Repeat

I use a few PowerShell scripts that end up triggering Service Management Automation (SMA) runbooks. Each time you want to use PowerShell to do that, you end up creating a one-time use SMA schedule. These one-time schedules are eventually cleaned up by SMA but they can clutter your view pretty well if you have a lot of them.

Luckily, there’s an easy way to use PowerShell to list SMA schedules that aren’t one-time use. We just want a list of all the SMA schedules that are repeating. You need the SMA PowerShell tools for this.

We’re going to get all the SMA schedules on our SMA implementation and get the ones where there is a NextRun value. The question mark is an alias for the Where-Object command and so we’re looking for schedules where $_.NextRun is true (has a value, isn’t null). I like formatting the output as a table for easier reading.

If a schedule has a NextRun attribute, it’s safe to say that it’s going to run sometime in the future and is not a one-time use schedule that’s already done it’s job.