Get RDS-CAL License Details (2008 RDS License Server)

Get current RDS-CAL details via PowerShell. Run this from your 2008 RDS Licensing server.

# Filename of the export
$filename = RDS-CAL-Report.csv
# Import RDS PowerShell Module
import-module remotedesktopservices

# Open RDS Location
Set-Location -path rds:

# Remove previous reports (Optional)
remove-item RDS:LicenseServerIssuedLicensesPerUserLicenseReports* -Recurse

# Create new RDS report
$NewReport = new-item -path RDS:LicenseServerIssuedLicensesPerUserLicenseReports -Scope DOM -Name Report

# Name is automatically generated
$NewReportName = $

# Get issued licenses
$IssuedLicenseCount = get-item RDS:LicenseServerIssuedLicensesPerUserLicenseReports$NewReportNameWin2K8-Win2K8R2IssuedCount
# Count issued licenses
$IssuedLicenseCountValue = $IssuedLicenseCount.CurrentValue

# Get installed licenses
$InstalledLicenseCount = get-item RDS:LicenseServerIssuedLicensesPerUserLicenseReports$NewReportNameWin2K8-Win2K8R2InstalledCount
# Count installed licenses
$InstalledLicenseCountValue = $InstalledLicenseCount.CurrentValue

# Installed - Issued
$Available = $InstalledLicenseCount.CurrentValue - $IssuedLicenseCount.CurrentValue
# Show percentage available
$AvailablePercent = ($Available /$InstalledLicenseCount.CurrentValue)*100
$AvailablePercent = {0:N0} -f $AvailablePercent

# Display info

Write-host Installed: $InstalledLicenseCountValue
Write-host Issued: $IssuedLicenseCountValue
Write-host Available: $Available [ $AvailablePercent % ]

# Add the information into an Array

[System.Collections.ArrayList]$collection = New-Object System.Collections.ArrayList($null)
$obj = @{
Installed = $InstalledLicenseCountValue
Available = $Available
AvailablePercent = $AvailablePercent
Issued = $IssuedLicenseCountValue
Date = get-date

# Exit RDS location
set-location c:

# Create PSO Object with the data
$collection.Add((New-Object PSObject -Property $obj));

# Export Data into a file
$collection | export-csv $filename -NoTypeInformation -Encoding UTF8

Quickly Check Domain Computers (Servers) for MS17-010 Patches

I put this script together from a few different sources.  It basically enumerates Active Directory and checks any 2008+ server for existence of KB patch for MS17-010.

MS17-010 patches a critical vulnerability discovered in Microsoft Windows operating systems that involve SMB exploits from a ShadowBrokers NSA dump of leaked NSA hacking tools.  It’s been spreading from CPU miner payloads to Ransomware (WannaCry/WannaCry 2.0) etc.

import-module activedirectory

$ErrorActionPreference= 'silentlycontinue'

# Server 2016 / Win10 - NT 10
# Server 2012 R2 / Win8.1 - NT 6.3
# Server 2012 / WIn8 - NT 6.2
# Server 2008 R2 / Win7 - NT 6.1
# Server 2008 / WinVista - NT 6.0
# Server 2003 R2 / WinXP64 - NT 5.2
# Server 2003 - NT 5.2
# WinXP - NT 5.1

$computers = get-adcomputer -filter * -properties * | select-object name,operatingsystem

$computers | foreach {
 $hotfixes = @()
 $osdetect = $_.operatingsystem
 $computer = $
 switch -wildcard($osdetect)
 "*Server*2016*" { $hotfixes = @("KB4013429", "KB4019472", "KB4015217", "KB4015438", "KB401663") }
 "*Server*2012*R2*" { $hotfixes = @("KB4012216", "KB4015550", "KB4019215") }
 "*Server*2012" { $hotfixes = @("KB4012217", "KB4015551", "KB4019216") } # A bit of a hack, not sure how this displays...
 "*Server*2008*" { $hotfixes = @("KB4012212") }
 default {$hotfixes = NULL } # Do nothing if it isn't a server and not 2008-2016.
 if ($hotfixes.count -gt 0) {
 $hotfixes | foreach {
 write-host "Checking $computer ($osdetect)..."
 if (!(get-hotfix -id $_ -computername $computer)) {
 write-host $computer "Missing ($_)"
 } else {
 write-host "Skipping $computer ($osdetect)..."

GPO Disable Password Expiration or Password Complexity

Big Fat Warning:  Don’t do this.

How to disable password expiration

  1. Load Local Group Policy Editor (Start –> Type gpedit.msc –> Enter)
  2. Expand sections: Local Computer Policy –> Computer Configuration –> Windows Settings –> Security Settings –> Account Policies –> Password Policy
  3. Set Maximum password age to 0 to completely disable passwords from expiring.

How to disable password complexity

  1. Load Local Group Policy Editor (Start –> Type gpedit.msc –> Enter)
  2. Expand sections: Local Computer Policy –> Computer Configuration –> Windows Settings –> Security Settings –> Account Policies –> Password Policy
  3. Set Password must meet complexity requirements to Disabled to completely disable password complexity requirements.

Remote WMI on Windows Server 2008 R2

Configure DCOM

  • On the server to be managed click Start, click Run, type DCOMCNFG, and then click OK.
  • In the Component Services dialog box, expand Component Services, expand Computers, and then right-click My Computer and click Properties.
  • In the My Computer Properties dialog box, click the COM Security tab.
  • Under Launch and Activation Permissions, click Edit Limits.
  • In the Launch Permission dialog box, select ‘Distributed COM Users’. In the Allow column under Permissions for User, select Remote Launch and select Remote Activation, and then click OK.
  • Under Access Permissions, click Edit Limits.
  • In the Access Permission dialog box, select ‘Distributed COM Users’. In the Allow column under Permissions for User, select Remote Access, and then click OK.
  • Add the user account to the Distributed COM Users Group in Computer Management, Local Users and Groups on the Server to be managed.
  • Add the user account to the Performance Log Users Group in Computer Management, Local Users and Groups on the Server to be managed.

Configure WMI

  • On the server to be managed click Start, click Run, type wmimgmt.msc, and then click OK.
  • In the console tree, right-click WMI Control, and then click Properties.
  • Click the Security tab.
  • Select the Root namespace and then click Security.
  • In the Security dialog box, click Add.
  • In the Select Users, Computers, or Groups dialog box, enter the user account. Click the Check Names button to verify your entry and then click OK.
  • In the Security dialog box, under Permissions, select ‘Enable Account’ and ‘Remote Enable’ for the user account.
  • Ensure the permissions propagate to all subnamespaces.

Remove Windows Defender from Server 2016

I have my own security software I use on Windows Server operating systems and take out Windows Defender.  Normally, I can do this through Feature removal, but the option to remove Windows Defender was unable to be removed from the manager.


To remove, I used Powershell.

Remove-WindowsFeature Windows-Defender, Windows-Defender-GUI


Sysprep Windows Server 2016 for Virtualization

Finally getting around to installing Windows Server 2016 (Standard, Desktop Experience) to use for application testing and upgrade plans this year.  I haven’t tested this release since Technical Preview 5 which had introduced the Nano edition.

I plan to create a sysprep image of the virtual machine so I can quickly deploy the system in the future.

What is sysprep?

The System Preparation (Sysprep) tool prepares an installation of Windows for duplication, auditing, and customer delivery. Duplication, also called imaging, enables you to capture a customized Windows image that you can reuse throughout an organization. Audit mode enables you to add additional device drivers or applications to a Windows installation. After you install the additional drivers and applications, you can test the integrity of the Windows installation. Sysprep also enables you to prepare an image to be delivered to a customer. When the customer boots Windows, Windows Welcome starts.

Since Windows 8 and Server 2012, there is a new command line switch for sysprep, /mode:vm.

Note:  This switch is only supported for virtual machines.  You can’t mix and match Hyper-V VMs and VMWare VMs.  Also, you cannot deploy this image to physical machine.

Install Windows Server 2016

First thing’s first, I’m going to install Windows Server 2016 Standard Desktop Experience.

Minimum System Requirements for Windows Server 2016 Standard (Desktop Experience):

  • 1.4 GHz 64-bit EMT64 or AMD64 processor
  • Support for security features like NX Bit and DEP (Data Execution Prevention)
  • The processor should support CMPXCHG16b, LAHF/SAHF, and PrefetchWNeeds
  • Needs to Support EPT or NPT (Second Level Address Translation)
  • 32GB disk space for Core, 4GB additional for GUI (Desktop Experience)
  • Needs to be a PCI Express Compliant Disk Controller.
  • ATA/PATA/IDE/EIDE are not supported for either boot, page, or data.

For my base system, I’m using a 50GB disk, 4GB RAM, and 1 socket, 2 core 2GHz vCPU.

Now that the base operating system is installed, I will do a few maintenance tasks that I like to do to my systems.

  • Windows Updates
  • Change Performance to High Performance

Once that is done, I can sysprep.

Sysprep the Windows Server VM

As noted above, the new flag (since Windows 8/Server 2012) /mode:vm allows for faster deployment, but you can’t switch between hypervisors after it is made and it cannot be deployed to physical hardware.  Once the sysprep is completed, the resulting VHD can be copied and attached to a new VM quickly.

c:windowssystem32sysprepsysprep.exe /oobe /generalize /shutdown /mode:vm

It will shutdown after sysprep completes, and at this point I can now simply clone the virtual machine to a new virtual machine.

After sysprep completes, I Clone the virtual machine in VMWare.  Once cloned, I power the virtual machine on and fill in the information at first startup as shown in the screenshots below.

Get Domain Users Last Logon and Account Status Windows Batch

A typical output of net user command produces 3 columns of usernames with the last row containing up to three columns.

kreider>net user

User accounts for \CTCRK-10

Administrator            DefaultAccount           Guest
The command completed successfully.

To filter this, I’ll use a for loop and set 3 tokens. Tokens 2 and/or 3 could be empty when we get the last row, as you can see.

@echo off
for /f "tokens=1-3" %%x in ('net users /domain^|find " " ') do (
 call :process %%x
 call :process %%y
 call :process %%z

if "%1"=="" goto :eof
REM echo User is %1
for /f "tokens=1-3" %%a in ('net user %1 /domain ^| findstr /r "active"') do (
 if "%%c"=="Yes" (
 for /f "tokens=1-5" %%e in ('net user %1 /domain ^| findstr /r "logon"') do (
 echo %1,ACTIVE,%%g %%h %%i
 ) ELSE (
 echo %1,DISABLED
:: other user processing here
goto :eof

The computer is unable to establish a trust relationship with the server. Verify that the computer’s date and time are accurate and try again.

Windows 7 SP1 x64 attempting to add to a 2012 R2 Essentials domain with Essentials Connector.

I verified date and time already.

Looking at the cert I think that is the problem.

Microsoft says to take a look at:

My problem is that I renewed the Server CA cert… and now the connector was using the incorrect.  So I need to install the latest CERT as a trusted cert on the machine giving me this problem:

  1. On the WHS, launch Certification Authority from the Administrative Tools menu
  2. Right-click on the <Server>-CA node and select Properties.
  3. In the Certificates tab of the Properties window, you should see at least two certificates, numbered sequentially.  Double-click the newest certificate.
  4. In the Certificate window, select the Details tab, and click the Copy to File button
  5. Step through the certificate export wizard, choosing any of the first three formats (I used the PKCS #7 format, and selected to include all certificates in the certification path).
  6. Save the file to a location that is accessible to the client you’re trying to connect (or a USB drive).
  7. On the client machine giving trust issues, open the certificate management console for the local computer by performing the following:
  8. From a Run line, enter mmc.exe
  9. In the empty console, go to File -> Add/Remove Snap-in
  10. Double-click Certificates
  11. Select Computer Account and click Next
  12. Choose Local Computer, and click Finish
  13. Find the Trust Root Certificates node, and expand Certificates
  14. From the Action menu, Choose All Tasks -> Import
  15. Ensure that the Store Location is Local Machine, and click Next
  16. Browse to the file you exported earlier, click Next
  17. Finish the wizard, and ensure that the new certificate appears in the certificate store
  18. Re-run the Connector software.  It should now run successfully.

Windows Server 2012 Essentials Connector Hangs on Windows 7

I am adding a Windows 7 x64 computer system to a 2012 R2 Essentials domain via the connector (http://server/connect) and it just sits and spins forever. Some digging around, I found that removing items in HKLMSYSTEMCurrentControlSetControlSessionManagerPendingFileRenameOperations and rebooting then reattempting to add the computer works.