Get VMWare network adapter types

This one requires PowerCLI to work, and you will need to connect to your vSphere server first; I wrote this one to see what servers had which network adapters configured so we'd know which ones could be upgraded to VMXNET 3.  This could easily be modified to capture just about any information you want, just by digging in to the VM objects a bit.

That's it; there's not much to this one other than what you see.  Use in good health.

EDIT: Well, this is embarrassing.  You could easily do the above faster and better  with "Get-NetworkAdapter (Get-VM)".  Well, this will work if you don't have Get-NetworkAdapter in your version of PowerCLI, or you could modify the above to target info that's not as readily available via cmdlet.

EDIT 2: "Get-NetworkAdapter (Get-VM)" won't show which server they're connected to, so I guess there is still use for my script.  I may circle around and update it using Get-NetworkAdapter, but for now, there you go.

Copy Group Policy links from one OU to another

Testing Group Policies can be a chore if you have a lot of them, especially if you need to link a long list of GPOs to one OU that are linked to another OU.  You could do this via the Group Policy Management console, but that can be time consuming, and you could wind up linking the wrong GPO or missing one if you're not careful.  So, let's script it, instead!

You will need to have the AD RSAT tools installed, and have the GroupPolicy module.  I've only tested this on Windows 8.1 with PowerShell V4, so your mileage may very (and, as this is one I've marked as "Dangerous", you absolutely should test this before using it in production, and be VERY careful: linking GPOs in the wrong place could have very bad adverse effects).

I highly recommend playing around with the output stored in $gpos; as you can see, what you want is nested fairly deeply ($gpos.gpos.gpo[*].LinksTo.SOMName).

Note that the SourceOU is the name of the OU itself, while DestinationOU is the full LDAP name.

I do very much recommend playing around with this on a test environment before going to town in production.

File server permissions audit

This is another one of those quick and dirty snippets to solve a problem or answer a question (I'm a real fan of those); it could easily be modified to create a much more professional looking report.

I was asked to go through a file server share and find out who had access to what at a pretty basic level; mostly, we're comparing groups in an old domain to make sure the corresponding groups have been set in the new domain, but this can be tweaked to help answer many questions.

I'm positive there's a better way to target only domain permissions without calling them directly, and when I find it, I'll come back and update this post; but for now, this works.  Note that to strip out inherited permissions, you will need at least version 3 of PowerShell (that property isn't returned by v2's Get-Acl).

Depending on the size of the file shares you target, this will very likely take a long time to complete, and could give your shell a nice, very large memory footprint, so you'll want to watch for that.  Once you have the output, though, you could easily do some quick manipulation in the shell, or export it to CSV and load it up into Excel to analyze it with pivot tables (the best reason for keeping Excel around, in my opinion).

Oh, and you will need access to read permissions on everything for this to actually work.

Update: There were issues with the original iteration of the snippet, mostly in that the output got messed up somehow when dealing with large-ish data sets (like you'd expect from any file server that's been in production for a length of time): it seemed to get "stuck" (for lack of a better word) on security principals and just list permission after permission tied to the same principal (which a quick sanity check against the file or folder's actual permissions showed to be false).  I solved that by outputing each object to a temporary csv file, then importing it back at the end of the process, rather than hold everything in a variable while it worked.

Bulk removing printers using WMI

The best way to do this is through Group Policy Preferences, but sometimes, we just need something quick and dirty.  If you have Server 2012 or Windows 8 (or newer), you have access to such wonderful cmdlets as Get-Printer and Remove-Printer to help you out; most of us, however, still have to work with Windows 7 and Server 2008 R2 frequently.  Fortunately, there's a way to do this using WMI, and I've written a quick snippet to show that off.

In my example, I needed to remove all of the printers on a server that came from one particular print server, and Group Policy wasn't really a good option at the moment.  Note the 4 backslashes at the beginning and 2 at the end; this is because of how WQL queries work, meaning you have to do a double backslash for every backslash to escape them.

You can also use SystemName instead of Name in the filter; if you do, leave off the ending backslash (or just leave all backslashes off; it should work just fine that way).

Warning: this code could potentially cause unexpected and bad results if you aren't careful.  I highly recommend testing before you use, and checking to make sure you've actually captured only the printers you want to remove by taking a look at what's in $printers before you run the last part (just do "$printers | select name" to see what printers you've targeted).

Updated About section

I've updated my about section with a few more details about me and what I'm doing.  Check it out; I'll be filling more in to it as time goes on and I have more to say there.

Simple Network Host Scan in PowerShell

This is very crass and simplified, and frankly, other programs (such as Angry IP and (my personal favorite) NMap) do a much, much better job; however, if you need to do a scan in a script for whatever reason, this may do the trick.  It would be very easy to make any changes to this you'd like, such as leaving out DNS resolution, or swapping it for a WMI query, or adding just about anything else you want.  This is just a quick, dirty example, and as such, it doesn't have a lot of polish.  (Note: as-is, this code requires Windows 8 due to Resolve-DnsName not being included in prior versions)

If you want to run this on Windows 7, here are two methods of resolving DNS names that work:

Using .NET methods (my preference):
Windows PowerShell One Liner: Name to IP Address

Using nslookup (more work to get the output you want, but always a good tool):
PowerShell v2 And DNS Queries

Removing the first or last lines from a text file

If you've ever run into a situation where you know you won't be needing those pesky first or last lines in a text file (this also works for other arrays, BTW), then this is a quick and easy way to get just what you're looking for:

Explanation: you can call a particular object by the index, or in this case, a particular line in the file.  Remember, the index number will be one number lower than the line number, because the index starts at 0, so line 20 will be at index 19, or $test[19].

You can also call a range of indices, such as to get lines 1 through 5, you would use $test[0..4].  You can use a variable number to specify the index as well, such as $test[$index].

Put this all together, and you can strip the last line out of your variable with:

Since the count is going to be the full number of lines, $var.count - 1 would be the last line, so you want it to stop at the next to last line, or $var.count - 2.

Removing the first line is likewise simple, with just a tiny modification:

If you need more than one line off of either side, just tweak the numbers.  Simple!

Get all events from a period of time

Sometimes when troubleshooting a problem, all you have to go on is an approximate time it happened (for instance, a report that a service was running slowly).  Going through all of the event logs by hand can be time consuming, but luckily, PowerShell can do that for you!

I ran into this scenario this morning, so the times on my snippet will reflect that:

I've multi-lined it to make it more readable.  Basically, it's getting a list of all of the Event Logs that PowerShell has access to, then expanding that list (so I get a list of strings rather than objects), and passing it to foreach.  Then, I can pass the current log name to Get-EventLog using the current-item variable $_, and tell it that I want to see what happened between the -After and -Before times.

Note: if you don't run this as Administrator, you'll get an access denied error when it tries to read the Security log; however, if you don't suspect what you need is in there (it probably isn't), this is actually a good thing as Security can be rather noisy without much useful information.

New bear in town

PowerShell.  It's the darling language of Microsoft now, and I've been working with it for a couple of years at this point.  With it, you can automate all manner of Microsoft products, from desktops and servers, to Exchange, to website creation with IIS, to just about anything you put your mind to.  It's an incredibly powerful .NET language that is also incredibly easy to use.  But, if you're here, you probably already know that.

So, where do I fit in?  I'm just another scripting monkey (or bear, as the case may be), right?  There are lots of tech writers out there who cover just about every aspect of the language already, so why do I need to chip in?  Really, because I want to, that's why.  Maybe I'll bring a unique perspective to the table, which someone finds valuable.

Regardless of what that is, I'll be writing about the things I find, the things I try, and the things I enjoy.  I'll write about PowerShell itself, as well as technologies that hinge on it, such as Exchange, Lync, Active Directory, and whatever I'm playing or working with this week.  As a more or less solo SysAdmin, I get a chance to play with a lot of different things, and the first thing I ask when trying something new is "How would I do this in PowerShell?"  When I answer that question, I'll post about what I figure out.

I hope this is a journey that we'll all be able to enjoy and learn from.