Posts

PowerShell Function to Extract Subnet/CIDR for a Pair of IP Addresses

Well, this one is hyper-specific... but in case anyone else needs to do something similar, I figure that I should share!  As a tiny part of a much bigger project, one of my customers gave me a list of VLAN IDs and the IP Ranges that they want to use on each VLAN.  Unfortunately, that list did not include either Subnet Mask or CIDR values, so I had to work backwards from the given ranges to determine what would be an acceptable Subnet Mask.  This process involves some annoying binary math, so you know that I put together a script to do it for me! I wrote the extract-CIDR function to accept two IP Addresses, and then to output the smallest subnet/CIDR that could contain those two IP Addresses (so they don't technically need to be the start and end of the range, but it's safer to use those two).  For example, if I give the script 192.168.0.1 and 192.168.0.254, I want to get back 192.168.0.0/24.  If I'm playing around with subnets though, I want to be able to give it 192.168.1.

Using Microsoft.Graph PowerShell Module to Update a Sharepoint List

I've been working on a big VMware automation project for a customer who wants to use their Sharepoint site as the source of authority for configuration files.  They are using Microsoft Graph to give me access to that environment, so my permissions do not extend to the standard PnP.Powershell module and I've been learning the Microsoft.Graph module instead. We came across an issue when using the new-MgSiteListItem cmdlet though, where we were getting error messages like "Field 'title' is not recognized."  In this case, there was a field called Title and the configuration that we'd passed the cmdlet specified Title, but the internal workings of the cmdlet were converting the first character to lowercase and thus the whole thing wasn't working.  But, there's an easy work-around! The Microsoft.Graph PowerShell module has a catch-all cmdlet: Invoke-MgGraphRequest.  With it, you can use the Graph API directly, without having to worry about headers and au

Powershell to Validate IP Configuration (Address, Gateway, Subnet Mask, DNS)

I'm working on a VM deployment script for one of my customers.  As you might expect, input validation is incredibly important, as we want to filter out a malformed configuration before starting the actual deployment.  To that end, I put together a bit of PowerShell that I'm pretty proud of; this script does a basic sanity check on a network configuration . It does a fair amount of work.  Firstly, it checks to ensure that the IP Address, Gateway, Subnet Mask, and all DNS Servers are being supplied as valid IP addresses.  PowerShell makes this trivial to do, as you can cast a string as an [ipaddress] object and PowerShell will parse it for you.  If it's a string that can't be parsed (such as [ipaddress]"JasonIsAwesome!" which is a string that most people would agree is inherently incomprehensible*), it'll throw an Exception and thus end the execution of the script.  So, that most basic input validation is over in a blink... but wait, there's more! Since

PowerCLI and Get-TagAssignment Execution Speed

I've been working on a script for a customer recently, and part of that script checks all of the VMs in their environment to ensure that they comply with the customer's VM Tagging policy.  As you might expect, this script revolves around the get-tagAssignment cmdlet and I've noticed an interesting quirk about how it runs!  I'm not clear on the "why" of it, but run these two commands and compare the results: measure-command {get-vm | get-tagAssignment} vs. measure-command {get-tagAssignment -entity (get-vm)} It's a profound difference!  In this customer's environment, piping the results of get-vm into get-tagAssignment takes over 73 seconds to run... but when I run get-vm as the entity for get-tagAssignment, it completes in a bit over 0.5 seconds! I'm not sure what's going on here, but I do know that once I changed my script to use the -entity property it sure ran faster!

Script to Move a VM to a New Portgroup and Update its Network Identity

Hey everyone - I recently put together a script to make it easier to move a VM around between various networks.  It moves the VM onto the specified Port Group and then uses VMTools to run a PowerShell script in the guest (this is for Windows VMs only, sorry!) to update its IP/DNS/Gateway/etc.  Since my old Gist'ing technique isn't working any more, so it's below as simple text (and it's on my GitHub if you want to grab it that way). But first, let's break it down a little bit!  The bulk of this script is really straight-forward.  The most interesting bit is using the PowerCLI Invoke-VMScript cmdlet to do the work inside the target VM's OS (since this operation will break network connectivity).  Invoke-VMScript is, on the surface, similar to the core PowerShell cmdlet Invoke-Command... but they way that they operate is completely different under the covers!  The practical difference that made the most impact for me is that Invoke-Command allows access to the par

Technique for Parsing String Output into PowerShell Objects

I just read a cool article about parsing netstat output (aka unformatted string output) into PowerShell objects.  The solution was great (and their approach taught me that select-object has a -skip # parameter that can be used to chop off the first # of objects from an array, which is super useful), but since I would approach it in a totally different manner, I figured that I'd write out my technique!  I want to be clear: I'm not saying that one approach is better than the other.  There are often many perfectly valid solutions to a scripting problem.  In some situations, one might be preferable to another though, and so here's another option to add to the old toolbelt. (netstat -an | ? {$_ -match '^  '}).trim() -replace '  +',';' | ConvertFrom-Csv -Delimiter ';' That's a pretty dense line (and it's worth noting that there are two adjacent space characters before the plus in the replace string and in the match string), so let's b

Planning VMware Upgrades

Image
System upgrades are a fact of life in the world of IT.  As systems grow more complex and interrelated, upgrades become more and more difficult to plan, as each of those interacting systems creates a dependency that may or may not support the new version!  In the VMware world, there's a couple of great tools that I use every time one of my customers asks for help with an upgrade project... so I figured that I'd write about them here! If the customer wants to upgrade their ESXi servers (which they almost always do), the first thing that I check is the VMware Compatibility guide .  When I'm using this tool, I typically select the new ESXi version under Product Release Version  and then just use the search bar to find the hardware platform that the customer is using.  After selecting the right server, the page will show us what firmware versions on that server platform are supported (or other interesting notes to be aware of).  These days, it's pretty rare for a server plat