Jun 082016

If you’re using Azure as an Active Directory lab and need to make sure your NTP is set properly with an external source, this is a good set of commands to run on your VM’s. I know Azure’s own built-in NTP synchronization system via HyperV is probably bar-none, but I’m trying to experiment with NTP settings on my PDC emulator and it just gets in the way.

I found this extremely useful tidbit of information here: https://blogs.technet.microsoft.com/keithmayer/2012/10/10/deploying-windows-server-2012-essentials-rtm-now-available/

Of course I lay no claim to this knowledge, it was pre-existing. I just added the little strike through below. 🙂

NOTE: Replace TIME_SERVER_x with time servers of your choice, hopefully Stratum 1.

If you run these commands, you will partially disable HyperV time integration.
Partially Disable Hyper-V Host Time Synchronization.

reg add HKLM\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\VMICTimeProvider /v Enabled /t reg_dword /d 0

Configure Windows Server Essentials to synchronize time with an external authoritative time server.

w32tm /config /manualpeerlist:TIME_SERVER_1, TIME_SERVER_2 /syncfromflags:MANUAL

Restart the Windows Time Service and force a time synchronization to occur.

net stop w32time && net start w32time
w32tm /resync /force




Jun 022016

So I have not posted anything to my blog for quite some time. I’ve decided to fix that, and I’m also changing the focus of my blog slightly from a broad catch-all for my technology interests to a more focused blog on what I’m learning with PowerShell, operating systems, and hardware.

First up is a new script I created to generate a server uptime report. Is also uses Microsoft SCCM WMI classes to determine if a reboot is pending (useful if updates delivered via SCCM didn’t trigger a reboot).

I also decided that I didn’t want to maintain a list of servers to query, so I have my script querying Active Directory OUs to compile the server list.

There are some things that you need to set in order to get this operational. The first is the list of OUs you wish to search. The other is information for the email report. The email stuff can be skipped if you wish, but I’ve found it quite useful, as long as you have an open SMTP relay.

Some things I need to do:

  • Allow toggle of CCM query. Not everyone has SCCM running.
  • Add optional authentication to email for relays that are not unauthenticated.
  • Additional error handling.

So here you go, and as always, let me know if you see something I can improve upon. I am learning this stuff after all.

#requires -Version 2 -Modules ActiveDirectory

# Author: Robert Hollingshead 
# Version: 1 
# Version History: First version. 
# Purpose: Get a list of servers based on arbitrary OU's, and then check each server for uptime. 
# Also grab pending reboot flag from CCM. Send as a report to an email address. 
# To-Do List: Allow toggle of CCM reboot-pending. Add optional authentication to mail. Additional error handling.

# Uncomment this to disable progress bar.
# $ProgressPreference = 'SilentlyContinue'

# Enter OUs to search here. One per line, follow the format below, omit comma on last line.
# You definately want to edit this stuff.
$OUsToSearch = @(
  'OU=Domain Controllers,DC=Contoso,DC=net'

# Enter your mail information here. 
$MailSender = '{sender email address here}'
$MailRecipients = '{recipient list here}'
$MailSubject = "Server UpTime Report for $(Get-Date -Format d)"
$MailBody = $MailSubject + ' is attached'
$MailServer = '{smtp server here}'

# Change nothing below this line. 
# ===============================

# Grab the class so that we can use convert to date fu nction. 
$WMI = [wmiclass]'\\.\root\cimv2:win32_operatingsystem'

# Set up some arrays. 
[system.array]$UpTimeReport = $null
[system.array]$Servers = $null

# Query Active Directory
ForEach ($OU in $OUsToSearch) 
  $OUResult = $null
    $OUResult = Get-ADComputer -SearchBase $OU -Filter * -ErrorAction Stop
    $Servers = $Servers + $OUResult
    Write-Warning -Message "Failed to get servers in $OU"

# Set up for progress bar.
[long]$totalitems = $Servers.count
[long]$progress = 1
[long]$percentage = 0

# Query each server for uptime. 
foreach ($Server in $Servers) 
  # Calculate percent complete and write-progress (if enabled)
  $percentage = ($progress * 100) / $totalitems
  Write-Progress -Activity 'Querying servers.' -PercentComplete $percentage `
  -Status "$percentage% complete..." -CurrentOperation "Checking $($Server.name)."

  # Attempt to get last bootup time and local date/time, then calculate. If fails, handle error. 
    $Stopwatch = Measure-Command -Expression {
      $OSProps = Get-WmiObject -ComputerName $Server.name -Class win32_operatingsystem -Property LocalDateTime, LastBootupTime
      $UpTime = $WMI.ConvertToDateTime($OSProps.LocalDateTime) - $WMI.ConvertToDateTime($OSProps.LastBootUpTime)
      $LastBootTime = $WMI.ConvertToDateTime($OSProps.LastBootUpTime)

      # Use CCM to determine if a reboot is pending.
      $CCMWmi = [wmiclass]"\\$($Server.name)\ROOT\ccm\ClientSDK:CCM_ClientUtilities"
      $Reboot = ($CCMWmi.DetermineIfRebootPending()).RebootPending
    $ServerUptime = "$($UpTime.days)+$($UpTime.Hours):$($UpTime.Minutes):$($UpTime.Seconds).$($UpTime.Milliseconds)"
    $TimeToRetrieve = "$($Stopwatch.Minutes):$($Stopwatch.Seconds).$($Stopwatch.Milliseconds)"
    $ServerUptime = 'Not Available'
    $LastBootTime = 'Not Available'
    $TimeToRetrieve = 'Failed To Retrieve'
    $Reboot = $false

  # Create object to be added to report. 
  $CurrentServer = New-Object -TypeName PSObject
  $CurrentServer | Add-Member -MemberType NoteProperty -Name 'ServerName' -Value $($Server.name) 
  $CurrentServer | Add-Member -MemberType NoteProperty -Name 'UpTime' -Value $($ServerUptime)
  $CurrentServer | Add-Member -MemberType NoteProperty -Name 'LastBootTime' -Value $($LastBootTime)
  $CurrentServer | Add-Member -MemberType NoteProperty -Name 'TimeToRetrieve' -Value $($TimeToRetrieve)
  $CurrentServer | Add-Member -MemberType NoteProperty -Name 'TimeRetrieveFinished' -Value $(Get-Date -Format T)
  $CurrentServer | Add-Member -MemberType NoteProperty -Name 'RebootPending' -Value $($Reboot)
  # Add to report object.
  $UpTimeReport = $UpTimeReport + $CurrentServer
  # Increment progress counter for progress bar. 

$ReportPath = $env:Temp + '\ServerUpTime.csv'
$UpTimeReport | Export-Csv $ReportPath
Send-MailMessage -From $MailSender -To $MailRecipients -Subject $MailSubject -Body $MailBody -Attachments $ReportPath -SmtpServer $MailServer
Dec 222014

This is an experimental PowerShell script that looks at all the physical network adapters on a machine and verifies that they are at or above an arbitrary link speed set in the script. It works by querying the MSNdis_LinkSpeed class in WMI, filtering out non-physical adapters, and then checking each one to make sure the link speed is above the $MinSpeed value that you set. It then returns TRUE or FALSE.

I believe it is useful to use a greator than or equal to comparison instead of saying that all links must equal the minimum speed, especially in server environments where you may have a mixed environment of some servers with gigabit links for instance, and then another set of servers or virtual machines with 10gig links.

I don’t see this being useful in a PC environment because you have less control over what a desktop is hooked in to at any given point in time. Though it may still be useful if you want to enforce such a policy, like trading floor must be at gigabit or higher, and you want to catch non-compliance.

Obviously I can’t account for every InstanceName that isn’t a physical adapter. If there is a better way, by all means let me know and I’ll modify the script, but here it is!

# Robert's experimental NIC speed compliance script. 
# Emphasis on EXPERIMENTAL. 
# It will not break anything but it may not give back a sane result. 
# Manually check suspect compliance, bad compliance will probably come
# from non-physical nics where I didn't account for the InstanceName
# below when it came from MSNdis_LinkSpeed. 

# Minimum allowed speed in megabits. 
$MinSpeed = '1000' 

# This is used for compliancy.
$NonCompliant = 0

# Get link speed for all physical network adapters. 
$nics = Get-WmiObject -Namespace root\wmi -Class MSNdis_LinkSpeed | where {`
$_.InstanceName -notlike '*miniport*' -and `
$_.InstanceName -notlike '*WAN*' -and `
$_.InstanceName -notlike '*1394*' -and `
$_.InstanceName -notlike '*ISATAP*' -and `
$_.InstanceName -notlike '*Bluetooth*' -and `
$_.InstanceName -notlike '*RAS*' -and `
$_.InstanceName -notlike 'Direct Parallel' -and `
$_.InstanceName -notlike '*tunnel*' -and `
$_.InstanceName -notlike '*6to4*' -and `
$_.InstanceName -notlike '*Deterministic*' -and `
$_.InstanceName -notlike '*miniport*' -and `
$_.InstanceName -notlike '*kernel*'

# Go through list of NICS and make sure speed is above $MinSpeed
foreach ($nic in $nics) {
    #Make the link speed in megabits instead of bits.
    $LinkSpeed = $nic.NdisLinkSpeed/10000

    #See if this NIC is compliant.
    if ($LinkSpeed -lt $MinSpeed) {

# Am I compliant?
if ($NonCompliant -eq 0) {
    write-host TRUE
    } else {
    write-host FALSE
Mar 142014

UPDATE: I’ve been clued in that Windows Performance Recorder is now capable of controlling the paging executive from its command line. https://msdn.microsoft.com/en-us/library/windows/hardware/hh448229.aspx (thanks Jeff Stokes)

Here is the registry change required to disable the paging executive for use with Windows Performance Recorder, but you can do it much easier with WPR now.

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory Management]

Alternatively, you can download the registry file as a ZIP here. disable_paging_executive.zip

Mar 112014

April 8th is fast approaching. On that date XP will end it’s 12 year run as a viable operating system. It will slip into the history books as a very successful Operating System of course, but it’s time for IT to move on to new and more capable operating systems.

XP will not go quietly into the night. It is still installed and used on a large number of PC’s and Point of Sale systems. What’s worse, because Microsoft will still be releasing security updates for NT 6.x (Vista/7/8/Server 2012), hackers will obviously be busy looking at those security updates to see if there are vulnerabilities in NT 5.x (2000/XP/Server 2003).

Unfortunately there are cases where, despite Microsoft’s insistence that we upgrade, it may not be possible to meet that April 8th deadline, so I’m publishing a list of things to do in order to harden the XP OS. The idea here is to make the XP OS difficult to exploit by anticipating problems with services and features that will no longer see updates from Microsoft.

Keep in mind this is my own list, there’s probably even better lists out there, but it’s a start:

  1. Kill unneeded services and disable them.

    Look for services that allow remote connections. For instance, if you can, kill and disable the server service. Here are a few. I’m also including a few that could be susceptible to MITM or other abuses later on in their life.

    Automatic Updates (Doesn’t make any sense to keep this running)
    Computer Browser (This will die anyway when the server service is stopped)
    Remote Desktop Help Session Manager (Potential for abuse)
    Remote Registry (Keep remote people/computers from breaking in to the registry)
    Routing and Remote Services (If automatic. Potential for abuse)
    Server (Keep people/computers from connecting)
    Shell Hardware Detection (Prevents autoplay, potential for abuse)
    SSDP Discovery Service (UPnP, Potential for abuse)
    System Restore Service (prevent viruses from hijacking restore points).
    Terminal Services (prevent remote people/comptuers from breaking in through RDP)
    Themes (prevent vulnerabilities with themes)
    Web Client (potential for abuse of WebDAV)
    Windows Time (May fall to MITM, potential for abuse)

  2. Windows Firewall

    Keep the Windows Firewall running and be sure that any old ports that were previously opened are closed. “Tighter than Fort Knox” applies here.

    If possible, configure “Don’t allow exceptions.”

  3. Enforce a “Do Not Connect To The Corporate Network” policy.

    The last thing you want is for an unsupported and infected XP machine to become an infection vector. While you can’t necessarily prevent this without some form of network gatekeeper like Microsoft NAP or Cisco ISE, getting your people to understand the dangers by enforcing a policy is the first step.

  4. Install a Stand-Alone Virus Scanner

    You should already have a virus scanner on your XP machines. But if you don’t want these machines connected to your network, a stand-alone scanner that receives updates from an internet facing server is the way to go . Microsoft Security Essentials is one product, but may not be supported on XP much longer. Third party may be your best bet, or open source.

  5. Disable Network Access

    If you do not need network access, disable the network adapters both in windows and through the BIOS.

  6. Back Up Everything

    Backup your documentation, your OS files, your discs. Support tools and support documentation are a must. Make disk images. XP is now a legacy OS and should be treated as such. 10 years later if you suddenly need access to an XP machine, you’ll be glad you captured everything.

  7. Have an End of Life Support Plan

    Obviously you’re not going to get much help from Microsoft after April 8th, without spending millions of dollars, so having an EoL Support Plan for Windows XP is a good idea.

    It does not have to be an involved plan. One simple method would involve re-imaging if something breaks (remember 6, backup everything).

  8. Keep Spares Around

    Manufacturers are moving away from supporting XP. It’s a good idea to keep spare kit around in case an XP machine malfunctions. No need to go overboard and save every single piece of equipment. “organ harvest” spare components from other machines and keep them in a marked box.

I could go on, but I think these 8 steps are the most important. I am in no way advocating the use of XP in a network setting after April 8th. In fact I think it is very dangerous from an IT security standpoint. But reality dictates there will be a need for XP in a legacy capacity for the next several years. It helps to be smart with how to implement that legacy use of XP.

And I bid thee farewell to a legendary OS.