SMBv1 Solutions


It’s been weeks since the #WannaCry #WannaCrypt exploited thousands of computers across the internet. If you have been regularly patching your systems you would have been covered by the March 2017 update. The vulnerability used the legacy protocol SMB version 1 to propagate across the network once a machine was infected. Security experts and even Microsoft have been calling for the disabling and or removal of the SMBv1 protocol from Windows environments for quite some time.

A Little History

Introduced with Windows XP, the SMBv1 protocol has been installed and enabled by default on all Windows operating systems for backwards compatibility. SMB version 2 was introduced with Windows Vista/Windows Server 2008 adding additional security and performance. SMB version 3 was introduced with Windows 8/Windows Server 2012 adding even more performance and availability options.

But First…

Disabling SMBv1 across an enterprise is no small feat. There’s a process to follow, and there’s research that needs to be done ahead of time. There are basically three hang-ups that can keep you from disabling SMBv1 across the board:

  • Windows XP and Windows Server 2003 boxes still hanging around the network. You REALLY need to get rid of them.
  • Linux servers, appliances, or devices that share or access data over SMBv1. Check with your vendors on supporting SMB 2.
  • Network scanners or multi-function printers that scan to file servers using SMBv1. See if they can be reconfigured or updated to support SMB 2.

Do the work to identify these gotchas so that you can know where you can and can’t proceed with disabling the legacy protocol.


Note that when disabling the SMBv1 protocol you need to disable both the server-side (I’m sharing files with you) and client-side (you’re sharing files with me) of the protocol.

Get It Done!

You route to disabling SMBv1 depends on the tools at your disposal.

1. Batch files and psexec


2. Group Policy



I wrote a PowerShell tool to gather the SMB protocols that are enable/disabled on a Windows computer called Get-SmbStatus. You can use this tool for discovery before and/or after you make your changes.


You can pick up the PowerShell function Get-SmbStatus at the Technet Script Repository.

DEV Intersection Conference

DEV Intersection
DEV Intersection Conference

Last month I had the privilege to attend the DEV Intersection conference in Orlando, FL. Being a infrastructure engineer I stuck to the IT Transformation track which was stocked with great speakers and sessions. The general focus of the sessions and keynotes was utilizing Microsoft (and others’) technologies to move towards devops oriented processes. I was additionally grateful for the workshops focusing on leveraging Visual Studio Team Services with Visual Studio Code to write PowerShell infrastructure as code taught by Jeffrey Snover, Don Jones, and Michael Greene. They convinced me to finally switch to using Code as my PowerShell editor.

Another highlight of the conference was Jeffrey Snover’s keynote on the impending release of Azure Stack. He presented the value proposition of businesses and service providers being able to provide a subset of Azure services in places where the Azure public cloud doesn’t yet make sense. I really think this is more game changing then most people realize and will put Microsoft in a unique position to help businesses transition to the “cloud” both in architecture and destination.

For years I have been listening to podcasts, reading blogs, and watching training videos, and it was a real treat to finally meet some of these people in person, shake their hand, and thank them for their influence on my career.

People I’m glad to have met:
Jeffrey Snover
Don Jones
Orin Thomas
Tim Warner
Michael Greene
John Savill
Steven Murawski
Rich Campbell

I would definitely go to the DEV Intersection conference again (if/when it comes back to the south east). The next conference is October 31-November 2, 2017 in Las Vegas.

Disk Inventory with PowerShell

Hard Drive
Hard Drive

Almost every time I write a PowerShell script, tool, or module it is to scratch an itch that I have. The Get-DiskInventory script is not new to me, but I have recently published because I saw others needed the same type of tool.

Get-DiskInventory gets a list of disk (really volumes) on a local or remote computer and displays their drive letter, name, free space, capacity, used space, and % free. While new operating systems have Get-Volume, sometimes you need a tool to work with those “legacy” operating systems such as Windows Server 2008 R2.

Get-DiskInventory leverages Get-WmiObject to gather the necessary information and is compatible across all versions of Windows client and server.


Get your copy now from the TechNet Script repository.

Using PowerShell with SCCM Pending Updates

SCCM Pending Updates
SCCM Pending Updates

We’ve been deploying Microsoft updates with System Center Configuration Manager for a few months now. Each month we get a little better at the process and trust the system more. After approving each month’s patches, I kept finding myself logging into my servers to see if they had pending updates ready to be deployed at the next maintenance window. Logging into each server doesn’t scale, so I needed to find a way to automate the process using PowerShell.

After using a search engine I was able to find the correct WMI class that I could use to query for SCCM client software updates.

Once I had the proper namespace and class, I wrapped a function around it to get the information I need along with a simplified summary output.

Full Output (Default)

Summary Output

If I find that the computer I’m working on still doesn’t have the updates that I approved, I give it a good kick with the following three client actions from the same CMClient module :

Try it out for yourself.



Have you ever wanted to know if a user was valid, disabled, or expired? I created a tool to validate a username against Active Directory called Test-ADUser.

Example 1: Valid User Output

Example 2: An Expired User

Example 3:
Test-ADUser -username disableduser

Example 4:
Test-ADUser -username invaliduser

Get your copy today at the PowerShell gallery (Install-Module MrAADAdministration).

PowerShell and SCCM Client Actions

SCCM Client Actions
SCCM Client Actions

If you work with System Center Configuration Manager (SCCM) you will be familiar with the number client actions that you can execute. Some of these actions are used more often than others, and learning what each of them do is for another blog post.

In our quest to roll out automated patching with SCCM we found that we often needed to run these various actions to get the SCCM client to check back in for new policy and check for pending updates. After logging into a handful of computers to open the Configuration Manger client applet from Control Panel to perform a Machine Policy Retrieval and Evaluation Cycle, I had to stop myself and find a faster way.

“What if I could use PowerShell to do this for me?”

I started like I normally do trying to find a SCCM client module with built-in cmdlets, but that path led to futility. Thankfully I found @adbertram wrote a PowerShell module that could execute the proper WMI method for the client actions. I immediately downloaded the code and started to try it out. I found one problem: the functions only accepted a single computer name at a time. I asked Adam about it. He told me to go ahead and update the code, and do a pull request on Git. I said I’d be glad to, pretending I knew how to do any of that Git stuff. After updating the code and performing my first Git pull request, we now have a SCCM client module for invoking client actions on multiple computers.

Let me show you a few examples:

Check out the CMClient module on Github and the PowerShell gallery (Install-Module CMClient).

Send your positive feedback to me and your bugs and complaints to Adam.



Windows UpdateI’ve been working on a project to roll out automated patching to the servers in our environment. We have been using a combination of group policy and WSUS, which is a great solution, but it doesn’t allow for multiple maintenance windows. Since we are primarily a Windows shop we chose to use System Center Configuration Manger (SCCM) as our solution. If you’ve worked with SCCM you know that “it’s a full time job.” So over the last few months we’ve been carving off some servers from our WSUS and moving them to SCCM for patching. During the changeover we needed to verify if the server was  actually talking to SCCM instead of our existing WSUS infrastructure. For the first few servers I logged on and launched regedit.exe to look at the policy key HKLM\Software\Policies\Microsoft\Windows\WindowsUpdate. After doing this two (too many) times I realized this wasn’t going to scale. I put together a PowerShell script to read the registry keys we needed from one or more remote servers.

Introducing Get-WindowsUpdatePolicy

Now with a quick command I can see what WSUS server a computer is configured to use. Try it out, and let me know if you find it to be useful.

PowerShell Tip: Get-Clipboard

Often times I find myself working with lists of computers (servers) where I need to get some information from the servers (i.e. uptime, OS version, etc.), or I need to run a command against them. I typically gather the computer names into a list in Excel for data manipulation, then I save the list of computer names into a text file to use from PowerShell. Now with PowerShell 5 I have the ability to work with data from the clipboard. I can select the list of computer names, copy it to the clipboard, and from PowerShell convert the text list in my clipboard to an array of objects that I can feed into other commands (i.e. Get-ADComputer, Get-CimInstance, etc.).

list of Servers
Excel list copied to clipboard.

We selected the list of server names from Excel and copied them to the clipboard (Ctrl +C). Now we need to get the contents of the clipboard into PowerShell.

Notice the -match operator? When copying a list from Excel to the clipboard, Excel adds an additional carriage return. The regular expression ‘\S’ means match any non-white space characters.  By using the -match operator with this regular expression we are suppressing the extra carriage return (and any other empty lines).

Now let’s look at the results.

Now we can run some commands against our list like Get-Uptime.


Password Expiration Notification with PowerShell

Your password is expiringYou may have seen this message if you work from a PC connected to a domain. Windows is letting you know that your password is expiring soon, and you should change it. This is an extremely helpful feature provided you are using a Windows PC connected to your domain as your primary device. But what if you’re using a Mac, or a mobile device (i.e. phone, tablet), or if you have vendor AD accounts whose devices are not joined to your domain? I have received too many tickets from vendors not being able to successfully authenticate to the VPN due to their password expiring. Some VPN clients don’t allow the user to reset their password after their password has expired resulting in a password reset service ticket. If only there was a way to notify users before their password expires regardless of the device they’re using.

Introducing Send-ADUserPasswordExpirationNotification

I wrote a PowerShell module (MrAADAdministration) to send email notifications to Active Directory users whose passwords are expiring within a set number of days. The function Send-ADUserPasswordExpirationNotification by default gets all users whose passwords are expiring within 10 days and sends the user a friendly email to remind them to change their password.

Requirements and Features

The user must have an email address populated in their AD account. You can filter usernames by pattern and/or scope your search base via distinguished name. If you’d like to notify the users earlier than the default ten days, you can just set the NotificationStartDay parameter. Let’s look at how you’d implement this for your own domain.


Download the module from the PowerShell Gallery.

After you have installed the module, you may wish to customize the email notification message to include your service desk contact information. You can also modify the default parameter values for the from, to, and SMTP addresses.

After you have customized the message you’re ready to send your first test notification.


Assuming everything works you should receive two emails. One email will be the notification email informing you of your password expiring. The other email will be the detailed report of all evaluated user accounts and if they were sent a notification.

Once you have tweaked your default parameter values and notification message you’re ready to schedule the script to run via Task Scheduler on a daily or weekly basis.

We’ve been using this process for over a year now, and it’s helped cut down on many of the tickets for password resets.

But wait, there’s more..

There is more in the MrAADAdministration module, but we’ll save that for another day.

Azure IaaS Disk Add Error

Today I saw that one of our Azure IaaS VM’s was getting low in disk space. The VM was configured with a number of data disks in a storage pool so adding a disk to expand space would not be a problem. In fact we have done this quite a few times for this specific VM, so the process is all too familiar. However this time I ran into a problem. I stepped through the process to add a new disk using the Azure Portal and received the following error:

Azure Disk Add Error
Failed to attach new disk ‘disk13’ to the virtual machine ‘server01’. Error: CannotAddOrRemoveNetworkInterfacesFromARunningVirtualMachine: Secondary network interfaces cannot be added or removed from a running virtual machine.

Wait….what? I can’t add a disk because I can’t add a NIC when the machine is running? But I’m trying to add a disk not a network adapter! I attempted to stop the VM to see if I could add this disk while the VM was offline. “No soup for you!

Failed to stop the virtual machine ‘server01’. Error: Secondary network interfaces cannot be added or removed from a running virtual machine.

What? Now what do I do? I restarted the guest OS and attempted a redeploy of the VM, but nothing worked. I opened a ticket with Azure support. After walking the support technician through my issue he was also stumped. However after a few hours of research he came back with the solution which was to force the first (and only) network adapter to be primary through PowerShell.

After executing these commands the VM shutdown without warning or intervention after which I was able to add my additional data disk, power on the VM, and get back to work.

I’m glad to find a solution, but this is definitely a pain point. I don’t have access to the hypervisor to force stop or reset a VM to fix the configuration through Hyper-V Manager, Failover cluster manager, or System Center Virtual Machine Manager. I know that’s not going to happen ever with Azure, nor should it. This is just one of those edge cases where you have to reach out to support for help.

Nugget of Wisdom

Purchase your Azure support before you need it. When you’re in the thick of it you don’t want to be establishing a support contract which can take time before you can even open a ticket.