PowerShell: A Colourful Experience

4214_Powershell20blore-logo_png-550x0.pngOne of the topics I inject into every one of my classes (and frankly, most of my customer conversations) is how to do whatever we are doing in PowerShell.  Scripting is one of the ways I make my life easier, and I recommend my students and customers use the knowledge I share to make their lives easier.

One of the differences between a Command Shell window and a PowerShell window is the colours.  Command Shell is white type on a black background.  PowerShell is a blue background, with the type colours varying depending on the context… Yellow for cmdlets, red for errors, and so on.

One of my students recently told me that because of the issues he has with his eyes, he has trouble reading the red writing on the blue background, and asked if there was a way to change it.  I honestly had never thought of it… so I decided to do some research.

It turns out, according to what I discovered, it is possible to change a lot of the colours in PowerShell.  Let’s start by changing the colour of the error messages:

$host.PrivateData.ErrorForegroundColor = “Green”

So let’s see what that does:


Okay, that is much better.  We can also change the background colour of the error text (black by default), by using this:

$host.PrivateData.ErrorBackgroundColor = “DarkCyan”


Granted, I hate the colour, but once you know the command, you can play with the colours that you want.

As well, if you want to change the colour scheme of the entire console, you can use the following:

[console]::ForegroundColor = “Yellow”

[console]::BackgroundColor = “black”

Now we have the entire console in black, and the default text in yellow.

If you want to use these colours persistently, you can insert them into your profile… or just create a .ps1 file that you run every time you open PowerShell.

Jeff Hicks wrote a number of great scripts a few years ago that will let you manage your colour schemes, and they can be found here.  Unfortunately it is an older article and the images are gone, but the scripts are intact, and that is the important part.

Have fun!


IPv6: Be gone!

Let me start this piece by stating that I am not advocating that we all ignore IPv6.  There are many reasons to use it, and there is nothing wrong with it.  Sure, it is more complicated than we may like… but then again, so was IPv4 when we were first introduced to it.

But alas, if you and your organization are not using IPv6, then there is no reason to have it bound to your workstations, let alone to your servers.  Let’s get rid of it… for now, knowing we can come back and re-enable it with a simple cmdlet.

First, we need to see which network cards have IPv6 bound to it, with the following:

Get-NetAdapterBinding | where {$_.ComponentId -eq ‘ms_tcpip6’}

That will return a list of NICs that have IPv6 enabled, like so:


We can remove the binding from each adapter individually, like so:

Disable-NetAdapterBinding -Name “Wi-Fi 2” -ComponentID ms_tcpip6

Of course, then we would have to do it for each of our NICs.  Rather than doing that, it would be simpler to just use a wildcard, thus disabling it for all of our NICs simultaneously:

Disable-NetAdapterBinding -Name “*” -ComponentID ms_tcpip6

Of course, in order to do this, you must open PowerShell with elevated credentials, so make sure you Run As Administrator.

Once you have done that, you can then go back and get the same list.  Notice that the listings under Enabled all read False now.


Now, as you may have heard me say before, PowerShell is very easy to understand… it is almost as if it were post-troglodyte grammar.  Get-Thing! Disable-NetAdapterBinding!  So it stands to reason that the reverse of the Disable-NetAdapterBinding cmdlet would be… yes, you guessed it! Enable-NetAdapterBinding!  But this time, rather than using the wildcard, let’s just do it for the NIC that I am currently using:

Enable-NetAdapterBinding -Name “W-Fi 2” -ComponentID ms_tcpip6

From this, we will now get the following results:


…and just like that, we can now enable and disable a protocol on demand.

By the way, if you are not fond of ComponentIDs, you can also use the actual display names:


Of course, that is too much typing for a lot of people, so you could shorten it with wildcards… or you can just cut and paste the ComponentID cmdlets.

Have fun guys, and script on!



A PowerShell Gotcha

powershell1_thumb.jpgI was bulk-creating users for a test environment today, and in doing so, I borrowed a script from an article online, which set the password for all users to ‘Pa$$word’  I usually use a variation on the same for test environments, but I opted to leave this one as it was.  The script worked.

A few minutes later, I went to log on as one of the newly created users, and the computer returned ‘The password is incorrect.  Try again.’

I spent a few minutes troubleshooting, until I realized… PowerShell uses the dollar sign ($) for variables.  I deleted the users, then changed the script to use a password like ‘P@ssw0rd’.  Sure enough, it worked.

The moral of the story… When using PowerShell, remember that the $ means something, and might break things if you use it for other things.

Have fun!

Deleting User Profiles

“How do I delete old users from a Windows 10 computer? I log in as an administrator, navigate to c:\Users\, and delete their tree.”

NO!  In fact, HELL NO!

There are several reasons why you might want to delete a user profile from a computer. ranging from termination of employment to reallocation of systems to… well, you get the picture.  There are a few of ways you can do it, but there are only a couple of ways of doing it right,

Recently I was working with a client who encountered a situation where a few of his domain users’ local profiles were corrupted on a corporate system.  I told him that the simplest way of fixing the issue was to delete the user profile, so that when the user next logged on, it would re-create the profile for them.  They called me back a few minutes later reporting that they were now receiving the following message when the affected users logged in:

We can’t sign in to your account.  This problem can often be fixed by signing out of your account then signing back in.  If you don’t sign out now, any files you create or changes you make will be lost.

Okay, that led me to believe they had simply deleted the c:\Users\%username% directory, and we had to clean up that mess in the registry (under “KEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList”, delete any entries that have the .BAK extension).

Okay… now that we have learned how NOT to do it, here’s how you should do it:

1) Open Control Panel > System and Security > System in the affected machine.  The simplest way to do this in the more recent releases of Windows 10 is to click Run – sysdm.cpl.

3) In the Advanced tab of the System Properties window, in the User Profiles section, click Settings…


4) In the User Profiles window, click on the user you want to delete, and click Delete.


**NOTE: You will not be able to delete the account you are logged in as, nor the default Administrator account.

Of course, you will be asked if you are really really sure that you want to delete the account, and you can click Yes or No as you wish.

There are ways to do it in PowerShell… but they don’t seem to be very clear or very easy.  For this one time, I strongly suggest the GUI.

What is in a Name?

Recently a client asked me to build a series of virtual machines for them for a project we were working on.  No problem… I asked what they should be named, and the client told me to call them whatever sounded right.

That did not sound right… or at least, it turned out to not be right.  Indeed, the client had an approved server naming convention, and when the manager saw my virtual machines named VM1, VM2, VM3, and so on… he asked me to change them.

If we were talking about a single server, I would have logged in and done it through Server Manager.  But there were fifteen machines in play, so I opted to use Windows PowerShell from my desktop.

Rename-Computer –ComputerName “VM1.domain.com” –NewName “ClientName.domain.com” –DomainCredential domain\Mitch –Restart

The cmdlet is pretty simple, and allowed me to knock off all fifteen servers in three minutes.  All I needed was the real names… and of course my domain credentials.

The cmdlet works just as well with the –LocalCredential switch… in case you aren’t domain joined.


That’s it… have fun!

Default Gateway Corrections

PowerShell.jpgThe default gateway setting in Windows (and every other networked operating system) is a simple setting that tells your network interface card (NIC) where to send traffic when sending it outside of your domain segment.  More often than not, it will be the .1 address of a network segment (e.g.:, but that is not always the case.

It is one of those settings that you set once and forget it… It almost never needs to be changed… until it does.  Network reconfigurations do happen, and changing the default gateway is simple to do in the graphical user interface via the Properties window of your network interface, simply by modifying the appropriate field in the  Internet Protocol Version 4 (TCP/IPv4) properties.

But what if you need to do it for several machines?  Of course, PowerShell to the rescue!

First, you need to check what your NIC Interface Index is:


This will give you an output that looks like this:


As we see in this example, the server was moved from one network segment (10.128.43.x/24) to a new one (10.128.11.x/24).  Because of that, we need to assign a new Gateway in the proper network segment.

The Interface Index here lists as 3.  Remember that.

Before we add the new Gateway, we have to remove the old one.  Otherwise the NIC will have two gateways, and that can cause issues.

Remove-NetRoute -ifindex 3 -NextHop “”

Notice that we put in 3 for the ifindex (the Interface Index), and the old gateway in quotes.

Now that we have a clean slate, all we have to do is configure the new default gateway, with this:

New-NetRoute -interfaceindex 3 -NextHop “” -destinationprefix “”

Again, we change our interfaceindex to 3, and our NextHop to the proper gateway.  When you run these two commands, you should get the following output:


That’s all there is to it!  Of course, you may want to execute this script against a group of computers, but that’s for another time…




SCOM Prerequisites: A Web of Confusion

Microsoft’s System Center Operations Manager (SCOM) has several prerequisites that must be installed for each component, and frankly, some of those can be cumbersome to get around.  Of course, it is nice for the SCOM installation console to let us know that Report Viewer (a free download from Microsoft, link provided in the notifications window) is a prerequisite… but they do not tell you that System CLR Types for SQL Server 2014 are a prerequisite to Report Viewer, no link given (spoiler alert: it is a component of the SQL Server 2014 Feature Pack).

Of all the components, it is the SCOM Web Console that has the most prerequisites, and frankly some of them are easier to install than others.

WebConsole Prerequisites

We have our work cut out for us, it would seem… unless we use PowerShell!

Yes, we could much our way through the Add Roles & Features wizard in Server Manager… and if you are only installing it the once, then that is probably fine.  If you are a consultant and expect to be installing SCOM more than once in your client environments, I strongly suggest you grab these PowerShell scripts.

Of course, the Report Viewer Controls Check is still going to fail, but those prerequisites are really easy – the link for the Report Viewer is here, and I hope you took the opportunity to install the SQL Server 2014 Feature Pack before you do that.


Import-Module ServerManager

Add-WindowsFeature NET-Framework-Core,Web-Static-Content,Web-Default-Doc,Web-Dir-Browsing,Web-Http-Errors,Web-Http-Logging,Web-Request-Monitor,Web-Filtering,Web-Stat-Compression,Web-Metabase,Web-Asp-Net,Web-Asp-Net45,Web-Windows-Auth,NET-HTTP-Activation,NET-WCF-HTTP-Activation45 -restart

This should do it… you will need to reboot the server in order for a few things to register properly (ISAPI and CGI and all sorts of stuff), but when you restart the installer and check your prerequisites…

Prerequisites Passed

That’s what we want to see… so in a few minutes time (the web console really does not take a long time to install) you should be able to navigate to https://servername/OperationsManager and you will see…


Now go forth and script, my good man!

I am heading out of town for a week or R&R… See you next Friday!

SCOM Management Packs: Removing Foreign Languages

When you go to add Management Packs (MPs) to System Center Operations Manager, there is that temptation to be lazy and just add everything.  This will clog your environment with a lot of things you do not need… including MPs in languages that you likely do not speak, read, or care about (within the context of your SCOM environment).

Once you realize this is a lousy idea, it is usually too late… you’ve already done it.  You will want to clear out a lot of things… starting with those foreign languages.

You can delete them one by one of course… right-click on the MP, click Remove (or Delete).  This will be reasonably time consuming… so when this happened to me some time ago, I went looking online for a better solution.

John Savill, an IT writer and Microsoft MVP whom I have known and respected for many years, created a great script that I found.  I found it again recently in an article he wrote for IT Pro Today.  Essentially, it removes every MP that has a geo-tag (.KOR for Korean, .ITA for Italian, and so forth).

From the Operations Manager Shell, enter (or cut and paste) the following:

Get-SCOMManagementPack | where{($_.Name.Substring($_.Name.Length -4,4) -eq “.CHS”) -or ($_.Name.Substring($_.Name.Length -4,4) -eq “.KOR”) -or ($_.Name.Substring($_.Name.Length -4,4) -eq “.CHT”) -or ($_.Name.Substring($_.Name.Length -4,4) -eq “.ITA”) -or ($_.Name.Substring($_.Name.Length -4,4) -eq “.JPN”) -or ($_.Name.Substring($_.Name.Length -4,4) -eq “.RUS”) -or ($_.Name.Substring($_.Name.Length -4,4) -eq “.FRA”) -or ($_.Name.Substring($_.Name.Length -4,4) -eq “.PTB”) -or ($_.Name.Substring($_.Name.Length -4,4) -eq “.DEU”) -or ($_.Name.Substring($_.Name.Length -4,4) -eq “.ESN”) -or ($_.Name.Substring($_.Name.Length -4,4) -eq “.HUN”) -or ($_.Name.Substring($_.Name.Length -4,4) -eq “.NLD”) -or ($_.Name.Substring($_.Name.Length -4,4) -eq “.PLK”) -or ($_.Name.Substring($_.Name.Length -4,4) -eq “.PTG”) -or ($_.Name.Substring($_.Name.Length -4,4) -eq “.SVE”) -or ($_.Name.Substring($_.Name.Length -4,4) -eq “.TRK”) -or ($_.Name.Substring($_.Name.Length -4,4) -eq “.CSY”)} | Remove-SCOMManagementPack

(Note: John’s original script excluded a number of languages; I have modified the script to include Hungarian, Dutch,  Polish, Portuguese, Swedish, Turkish, and Czech. I do not know if these are languages that were added to Management Packs recently, but I found several with these and wanted to remove them as well.)

Depending on how many foreign language MPs you have, it might take some time… After all, it is going through and removing them individually the same way that you would… but without having to right-click, click, confirm, repeat.  So be patient… it is working!

(Note: While it is working, you will not be able to access the Operations Console… at least, not from the same system you are running the script on.)


The article I found it in is here, and while it was originally written for SCOM 2012, it works just as well for SCOM 2016.

Thanks John!

Operations Manager: How to List What Management Packs Are Installed?

A client asked me recently how to determine what Management Packs he had installed in his System Center Operations Manager (SCOM) infrastructure.  I told him to open his Management Console and navigate to Administration – Installed Management PacksIt was a short conversation.

SCOM Installed MPs

Easy peasy, right?  Here’s a list, go with G-d.  Twenty minutes later, my phone rings again.

“Mitch, how can I export that list so that I can include it in our Infrastructure Documentation?”

Aha… That is a different kettle of fish.  For this, we will go into the Operations Manager Shell, essentially the PowerShell console for SCOM.  The command most people seem to recommend, to stick to pure PowerShell scripting, would be:

Get-SCOMManagementPack |ConvertTo-Csv | Out-File c:\MPs\InstalledMPs.csv

This will give you a .CSV (comma separated values) file with the following information:

  • Name
  • TimeCreated
  • LastModified
  • KeyToken
  • Version
  • ID
  • Identifier
  • VersionID
  • References
  • Sealed
  • ContentReadable
  • FriendlyName
  • DisplayName
  • Description
  • DefaultLanguageCode
  • ActiveLanguageCode
  • LockObject
  • Store
  • SchemaVersion
  • OriginalSchemaVersion
  • Registry
  • Extensions
  • LifetimeManagers
  • Features
  • ImageReferences
  • EntityTypes
  • ManagementPacks
  • Presentation
  • Monitoring
  • DerivedTypes

…in other words, way more information than we need.  I generally cheat and use the following (from my Batch File days):

Get-SCOMManagementPack >”c:\MPs\InstalledMPs.txt”

This creates a text file with exactly what would be displayed if I ran this cmdlet on the screen…

SCOM Installed MPsTXT

Ok, that is a lot more useful than the whole CSV list, but I might want to select only the columns I want, and not the ones that PowerShell thinks I want.  Let’s try this:

Get-SCOMManagementPack | Select-Object Name,FriendlyName,Description | ConvertTo-Csv | Out-File c:\MPs\InstalledMPs.csv

Now I have a usable file (.csv imported into Excel is a lot more useful than a text file that I can only manipulate in Notepad), that has exactly the information I want… in this case, I have the Name, the Friendly Name, and the Description.  My output might now be formatted to look like this:

SCOM Installed MPs-Formatted

Much better, don’t you think?  If we are doing this for the sake of documentation, we should be able to make it as legible as possible.

Of course, you can choose your objects (columns) as you choose… just replace the names in my Select-Object entry with the ones you want (from the list above, separated by commas).  Then you can import your list into Excel.  Do not try to open the file in Excel by double-clicking… that will not do anything with your CSV formatting, and it gets ugly.

Have fun!

SCOM License – Upgrade?

The installation of System Center Operations Manager (SCOM) 2016 does not ask you anywhere to enter a license key.  Then when you run the Operations Console, you are shown a required task to Upgrade to full version.  When you click on the link, it opens a website that is less than helpful.

SCOM Upgrade to Full

In fact, when you open the Help – About, you get a nice screen that says the product is not licensed to anyone, and you are using an Eval copy.

SCOM Unlicensed

All this is saying is that we have not yet entered a product key for SCOM.  For reasons I have never quite understood, there is no way to enter the license key in the GUI; you have to enter it in the Operations Manager Shell (essentially the PowerShell for SCOM), and you have to do it directly from the Management Server.

The command is: Set-SCOMLicense -ProductID “XXXXX-XXXXX-XXXXX-XXXXX-XXXXX”.

SCOM ProductID

Once you do this, the Upgrade Required notice will disappear (when you restart the Management Console), and your product version in the About section will now appear as Retail.

SCOM Licensed

Note: If you have any problems getting this to work with the Shell, try running the Operations Manager Shell as Administrator.

Active Directory Recycle Bin

A few years ago, Microsoft introduced the Active Directory Recycle Bin to Windows Server.  Wonderful!  It is not enabled out of the box, but it is reasonably simple to enable… except, it is not.

Firstly, you can do it in the GUI… Open the Active Directory Administrative Center, navigate to local (local), and then in the Actions Pane click Enable Recycle Bin…  You will get a warning about how serious this is – that is, it is irreversible.  Thanks, let’s go ahead.  We’re done.

The other way to do it, and obviously my preferred method, is with PowerShell.  Use the following cmdlet:

Enable-ADOptionalFeature –Identity ‘CN=Recycle Bin Feature,CN=Optional Features,CN=Directory Service,CN=Windows NT,CN=Services,CN=Configuration,DC=local,DC=domain,DC=name’ –Scope ForestOrConfigurationSet –Target ‘local.domain.name’

Once again, you will get a warning that “Enabling ‘Recycle Bin Feature” is an irreversible action! You will not be able to disable ‘Recycle Bin Feature’ on ‘CN=Partitions,CN=Configuration,DC=local,DC=domain,DC=name’ if you proceed.”

(Yes, the warning is in orange… not my choice)

You press YES, you go ahead, and it’s done…

…or IS IT?

“A referral was returned from the server”

This error can come equally and identically from the GUI as from PowerShell… It simply means, THIS DID NOT WORK.

I have read all sorts of articles and forums on this, people telling people that they had the syntax wrong.  “Change single quotes to double quotes, or remove the quotes, that’s what will work.”  Some of these may be accurate.  In my experience, it is not a syntax error.

There are five (5) Flexible Single Master Operations (FSMO) roles on our domain.  Two of these, namely the Schema Master and the Domain Naming Master have to be on the same domain controller in order for this to work.  Otherwise… no.

I should also take a moment to mention that anytime you are doing anything with the Schema Master role, you have to be a member of the Schema Administrators security group.  I hear from people all the time ‘…but I am a member of the Enterprise Admins group!’ Nothing doing… except that, if you are a member of the EA group, you can add yourself pretty easily to the SA group.

So… transfer the Schema master role and you will be fine.  Good luck!

Oh yeah… here’s how.

  1. Use ntdsutil.exe.  I will not bore you with the details… somewhere under roll – connections – servers – bla bla bla.
  2. Use PowerShell.  Here’s your cmdlet:

Move-ADDirectoryServerOperationMasterRole -Identity “Target-DC” -OperationMasterRole SchemaMaster

Let me know if you run into any further issues, but this should solve it for you!

DCPromo No More… PowerShell!

I needed to build a new domain controller for a friend’s company recently.  It is something that I have done so many times over the past two decades that some things are just instinctive… like typing dcpromo to create a domain controller.


Right… I had forgotten about that.  dcpromo has been deprecated.

You could go through the process of doing it through the Server Manager, but it really is more work than is needed.  Instead, try the following PowerShell script::

# Script to create Active Directory Domain Controller.
# Written by Mitch Garvis for Cistel Technologies Inc.
# Enjoy!

# Install Active Directory

Install-WindowsFeature AD-Domain-Services -IncludeManagementTools

# Create Domain Controller

Import-Module ADDSDeployment
Install-ADDSDomainController `
-NoGlobalCatalog:$false `
-CreateDnsDelegation:$false `
-CriticalReplicationOnly:$false `
-DatabasePath “C:\Windows\NTDS” `
-DomainName “domain.com” `
-InstallDns:$true `
-LogPath “C:\Windows\NTDS” `
-NoRebootOnCompletion:$false `
-SiteName “Default-First-Site-Name” `
-SysvolPath “C:\Windows\SYSVOL” `

That should do it… just change where it says ‘domain.com’ to whatever domain you want to use.  Run it.  In a couple of minutes, you will be asked to enter a Safe mode Admin password.  A few minutes after that, you should have a brand new domain controller.

Remember, depending on the size of your Active Directory, it may take several hours to replicate to the new DC… so give it time 🙂

Renaming Files en Mass…

Nikon D5100I take a lot of pictures… not only with my phone, but also with my Nikon DSLR camera.  It is one of my hobbies… I am not very good at it, but I enjoy it nonetheless.

Keeping track of hundreds or thousands of pictures is easy, as long as you copy them into the appropriate directory in your computer.  It is easy to keep track, so I might have the following files in a directory:

Volume in drive E is SWMI Blue-2T
Volume Serial Number is 9ED7-318E

Directory of E:\Holiday Snaps

2017-12-19  03:26 PM    <DIR>          .
2017-12-19  03:26 PM    <DIR>          ..
2017-12-19  03:26 PM                 0 dir.txt
2008-05-25  03:54 PM         3,102,650 DSC_0001.JPG
2008-05-25  03:55 PM         3,107,741 DSC_0002.JPG
2008-05-25  03:54 PM         3,102,650 DSC_0003.JPG
2008-05-25  03:55 PM         3,107,741 DSC_0004.JPG
               5 File(s)     12,420,782 bytes
               2 Dir(s)  280,903,417,856 bytes free

That is great… except for the fact that if I search my hard drive for a file named DSC_0004.JPG, I might have hundreds of them, depending on how my camera is configured. So what I like to do is rename all of my files from a specific event, like so:

E:\Holiday Snaps> ren DSC_0*.* HolSn*.*

E:\Holiday Snaps> dir

Volume in drive E is SWMI Blue-2T
Volume Serial Number is 9ED7-318E

Directory of E:\Holiday Snaps

2017-12-19  03:30 PM    <DIR>          .
2017-12-19  03:30 PM    <DIR>          ..
2017-12-19  03:26 PM               553 dir.txt
2017-12-19  03:30 PM                 0 dir1.txt
2008-05-25  03:54 PM         3,102,650 HolSn001.JPG
2008-05-25  03:55 PM         3,107,741 HolSn002.JPG
2008-05-25  03:54 PM         3,102,650 HolSn003.JPG
2008-05-25  03:55 PM         3,107,741 HolSn004.JPG
               6 File(s)     12,421,335 bytes
               2 Dir(s)  280,903,417,856 bytes free

Great… I now have my files named HolSn (for HOLiday SNaps).  If I only go on holiday once in my life, I am set.

What I want to be able to do is to rename the files with more descriptive names… like Havana July 20170001.JPG, and so forth… and if I only have four or five pictures, that is easy enough.  With hundreds and often thousands of pictures, it can be ridiculously laborious.  So instead, we are going to use some old Command Prompt/Batch Magic.  Watch this:

E:\Holiday Snaps>for /f %a in (*) do ren “%a” “Havana July 2017 %a”

E:\Holiday Snaps> dir

Volume in drive E is SWMI Blue-2T
Volume Serial Number is 9ED7-318E

Directory of E:\Holiday Snaps

2017-12-19  03:42 PM    <DIR>          .
2017-12-19  03:42 PM    <DIR>          ..
2017-12-19  03:42 PM                 0 dir.txt
2008-05-25  03:54 PM         3,102,650 Havana July 2017 DSC_0001.JPG
2008-05-25  03:55 PM         3,107,741 Havana July 2017 DSC_0002.JPG
2008-05-25  03:54 PM         3,102,650 Havana July 2017 DSC_0003.JPG
2008-05-25  03:55 PM         3,107,741 Havana July 2017 DSC_0004.JPG
               5 File(s)     12,420,782 bytes
               2 Dir(s)  280,903,409,664 bytes free

That is more like it.  So when you want to rename your files in a Command Prompt, just follow those easy steps.


Yes, I know… Command Prompt is out, PowerShell is in.  Also simple…

Get-ChildItem | Rename-Item -NewName { “Prefix_” + $_.Name }

This will do the same thing, but you have to be running a version of Windows with PowerShell… so, not Windows XP! Smile

PS E:\Holiday Snaps> ls

    Directory: E:\Holiday Snaps

Mode                LastWriteTime         Length Name
—-                ————-         —— —-
-a—-       2008-05-25   4:54 PM        3102650 DSC_0001.JPG
-a—-       2008-05-25   4:55 PM        3107741 DSC_0002.JPG
-a—-       2008-05-25   4:54 PM        3102650 DSC_0003.JPG
-a—-       2008-05-25   4:55 PM        3107741 DSC_0004.JPG

PS E:\Holiday Snaps> Get-ChildItem | Rename-Item -NewName { “Havana July 2017-” + $_.Name }
PS E:\Holiday Snaps> ls

    Directory: E:\Holiday Snaps

Mode                LastWriteTime         Length Name
—-                ————-         —— —-
-a—-       2008-05-25   4:54 PM        3102650 Havana July 2017-DSC_0001.JPG
-a—-       2008-05-25   4:55 PM        3107741 Havana July 2017-DSC_0002.JPG
-a—-       2008-05-25   4:54 PM        3102650 Havana July 2017-DSC_0003.JPG
-a—-       2008-05-25   4:55 PM        3107741 Havana July 2017-DSC_0004.JPG

PS E:\Holiday Snaps>

I hope this helps…. now if you don’t mind, for some reason I am thinking I should book a vacation!

Scheduling Server Restarts

If you manage servers you have likely come to a point where you finished doing work and got a prompt ‘Your server needs to reboot.  Reboot now?’  Well you can’t reboot now… not during business hours.  I guess you’ll have to come back tonight… or this weekend, right?

Wrong.  Scheduling a reboot is actually pretty easy in Windows.  Try this:

  1. Open Task Scheduler (taskschd.msc).
  2. In the Actions pane click Create Basic Task…
  3. Name the task accordingly… Reboot System for example.
  4. On the Task Trigger page click the radio button One Time
  5. On the One Time page enter the date and time when you want the server to reboot.
  6. image
  7. On the Action page select Start a program.
  8. On the Start a Program page enter the name of the program shutdown.exe.  In the Add arguments box enter /f /r /t 0.  This will force the programs to close, restart the server (instead of just turning it off), and set the delay time to 0 seconds.
  9. image
  10. Once you have done this your server will reboot at the precise time you want it to, and will come back up.

**NOTE: Don’t forget to check.  it is not unheard of in this world for servers to go down and not come back up as they are supposed to!

Do it in PowerShell!

Using PowerShell to script this will allow you to not only save the script, but also run it on remote servers.  From Justin Rich’s blog article I found this script:

register-ScheduledJob -Name systemReboot -ScriptBlock {

Restart-Computer -ComputerName $server -Force -wait

Send-MailMessage -From mitch@email.com -To mitch@email.com -Subject "Rebooted" -SmtpServer smtp.mail.com

} -Trigger (New-JobTrigger -At "04/14/2017 8:45pm" -Once) -ScheduledJobOption (New-ScheduledJobOption -RunElevated) -Credential (Get-Credential)


Have fun!

Resize Live Virtual Hard Drives


I have used Hyper-V for as long as there has been Hyper-V.  Today I use it much less than I once did, but it is still handy for running VMs on my laptop.  I run a particular VM called ‘Sandbox’ in which I do all sorts of things that I would not want to do on my live system… things that I can simply try and then wipe.

When I built the Sandbox VM I was spending a lot of time at home, and portability was not a huge issue.  I ran it on one of my external drives, and it worked fine.  I allocated 100GB and was good to go.

When I realized I was going to be on the road again I could just as easily take my external hard drive with me, but the shortage of USB ports on my Surface Pro meant making a decision… I was going to shrink the VHDX file and put it on my internal hard drive.

76GB free space.  That’s going to be a problem.

Step 1: Shrink your partitions

My 100GB virtual hard drive (.vhdx file) meant that somewhere within the VM I had a 100GB partition (or at least a few partitions that added up to that).  I had to shrink as much as I could.

  1. If you have a Pagefile.sys, Swapfile.sys, and Hiberfil.sys you should eliminate them now.  Remember that even if you turn off Memory Paging the files don’t disappear until you reboot.
  2. Defragment the disk.  We may not talk much about it anymore, but the old faithful defrag.exe C: still works. 
  3. Use the Disk Manager console to shrink your C: as much as you can… but not too much.  When I tried it I had the option to shrink it down to 11.5 GB… I’m pretty sure that would render my VM pretty useless.  Pick a number that works for you.  I chose 60GB.
  4. Using the diskpart tool delete any partitions at the end of your drive.  I had a 450MB Recovery partition on mine.


Because it was a Recovery (read: SYSTEM) partition I needed to do the following:

Select Partition 5

Delete Partition OVERRIDE


Good… Now we can shrink the VHDX file.

In the older versions of Hyper-V this would have meant shutting down the VM.  You don’t have to do that anymore… but you do have to run PowerShell as an Admin.  Once you do:

Step 2: Shrink your VHDX file

The cmdlet is easy…

  1. Navigate to the directory where you keep your VHD file;
  2. Resize-VHD -Path .\Sandbox-PC.vhdx -SizeBytes 60GB

It will only take a minute and you will be done.  Simple as pie!