Windows 10 1909 scan and install updates using PowerShell

Apparently this only works in build 1909 and was removed from later versions. This can be started remotely if remote management is configured properly and the necessary firewall ports are open.

Install-WUUpdates -Updates (Start-WUScan)

To break this down in more detail:


This, by itself, will scan for updates and show the output in the terminal.

$Updates = Start-WUScan

This runs the scan and puts the results into a variable, which would make it easier to filter if you only want to install certain updates.

Install-WUUpdates -Updates $Updates

If you’re storing the update results in a variable, use this command. Otherwise, the command at the top of the page is the most direct way to scan and install updates in one shot.

Cleanup old demoted Domain Controller DNS records

Clean up Domain Controller DNS Records with Powershell

$dnsrecords = Get-DnsServerResourceRecord -ZoneName “” -ComputerName dc1
$deadDC = $dnsrecords | Where-Object {$_.RecordData.IPv4Address -eq “” -or $_.RecordData.NameServer -eq “” -or $_.RecordData.DomainName -eq “”}
$deadDC | Remove-DnsServerResourceRecord -ZoneName “” -whatif -ComputerName dc1
$deadDC | Remove-DnsServerResourceRecord -ZoneName “” -ComputerName dc1

Office 365 / Exchange Online get sizes of mailbox/folders and archive, turn on automatic expanding archive

Show the retention policy applied to the mailbox: Get-Mailbox “username” | select retentionpolicy

Show the size of all folders in the mailbox: Get-MailboxFolderStatistics “username” | select Name, FolderandSubFolderSize

Same thing for the Archive mailbox: Get-MailboxFolderStatistics “username” -Archive | select Name, FolderandSubFolderSize

See if the mailbox’s automatic expanding archiving is turned on: Get-Mailbox “username” | select AutoExpandingArchive

If that is false, turn on the feature: Enable-Mailbox “username” -AutoExpandingArchive

To create a new archiving policy to move mail to the Online Archive sooner, compliance management > retention tags. Create a new tag, set it to Default and the number of days. Then go to retention policies and either create a new policy or change an existing policy to include the new Default retention tag (removing an existing one if it’s there – I assume you can’t have two Default tags in one policy). Then change the user’s mailbox to use the new policy.

Set-Mailbox “username” -RetentionPolicy “Policy name” or this can be done through the ECP.

Run as a different user / add user to local groups on an Azure AD joined machine

On an Azure AD joined PC, I was in a remote session with a user trying to install something. Since the user didn’t have admin privileges, any time a UAC prompt appeared, the remote session would pause and I wouldn’t be able to enter my admin login details.

To get around this, open command prompt and run

runas /noprofile /user:azureAD\ cmd

Since I’m an admin who joined the machine initially, my user account has admin rights, so the CMD prompt and processes launched from it run with local admin privileges. For example, I can run lusrmgr.msc (local users and groups) or net user to create a local admin user or add a user to the local administrators group.

When adding an Azure AD user to the local administrators group, use the same AzureAD\ syntax.

When installing software by double clicking an EXE file, I recommend moving it to c:\users\public first to ensure the file is accessible by your admin user (it won’t be if it’s in the user’s profile directory because of NTFS permissions). Then hold down Shift, right click the EXE, and choose run as different user. Enter your administrative credentials. In my case, a UAC prompt appeared, which I couldn’t click on from the remote session, but since it was running with elevated/admin privileges, the user was able to simply click Yes (rather than typing in any login details) and the installation started successfully.

Changing Lenovo BIOS settings using PowerShell (enable Wake on LAN)

From an (administrator) PowerShell prompt, run the following to view the current BIOS settings and the selected choices (you may have to change the double quotation marks to the “standard” ones if WordPress changes them to the fancy versions):

gwmi -class Lenovo_BiosSetting -namespace root\wmi | ForEach-Object {if ($_.CurrentSetting -ne "") {Write-Host $_.CurrentSetting.replace(","," = ")}}

For example, to change the Wake on LAN setting to the Primary option, use the following syntax:

(gwmi -class Lenovo_SetBiosSetting -namespace root\wmi).SetBiosSetting("Wake on LAN,Primary")

Important: once you’re done changing one or more settings, you have to save your changes with this command:

(gwmi -class Lenovo_SaveBiosSettings -namespace root\wmi).SaveBiosSettings()

When running Set or Save commands, a result will be returned, either success or failure:

__GENUS : 2
__PATH :
return : Success
PSComputerName :


Click to access wmi_dtdeploymentguide_m92.pdf

Select unique items from a list in PowerShell

I had a list of mobile devices (get-mobiledevice) to disable. To check their CASMailbox properties afterwards, select the column and use Sort-Object with the Unique parameter to avoid running commands multiple times (if one person had multiple mobile devices)

$DisableMobiles | select UserDisplayName | Sort-Object -Property UserDisplayName -Unique

Then I used this command to run the de-duplicated list of names through get-casmailbox:

| % {get-CASMailbox $_.UserDisplayName | select name, *all*id*, *bl*id*}

Finding memory leaks that don’t show up in Task Manager

Windows: Finding a driver which leaks memory

View at

2020-04-14 12_29_37-Clipboard

On the affected system, this is task manager looks like. The Paged pool and non-paged pool values are very high. None of the processes listed under the Processes tab have very high memory usage, so it’s not a user mode process that’s causing the issue.

2020-04-14 12_37_08-Clipboard

To track this down, you’ll need poolmon.exe. This can be obtained from the Windows Driver Kit, which claims to require Visual Studio, although some people say this isn’t necessary. I found it easier to download use the Windows Server 2003 support tools:

After installing, you can find it here: “C:\Program Files (x86)\Support Tools\poolmon.exe”

Run poolmon.exe /b from an admin command prompt. The /b flag sorts by bytes, i.e. putting the highest memory usage items at the top of the list.

2020-04-14 12_28_20-Clipboard

The first entry, FMfn, is using 1,274,642,288 bytes of memory – or 1.27 GB. Ntff is using around 500 MB. Those two are of the Paged type, which explains why the Paged pool in Task Manager is so large at 3.8 GB. On my properly working system, FMfn is using only 84,776,224 bytes and Ntff is using 59,586,560 bytes (and the entire paged pool is only ~800MB).

To find out what those are, run these commands:

First, cd \Windows\System32\drivers


findstr /m /s /l FMfn *.sys (replacing FMfn with the Tag listed by poolmon)

2020-04-14 12_47_57-Window

In this case, FMfn is fltmgr.sys, which is a Windows file system filter driver. The culprit is probably a third party filter that’s leaking memory, but I haven’t tracked that down yet. The easiest way to (temporarily) resolve these problems is to reboot, but of course, the leak will probably come back over time.

–Here’s how to track down what’s happening more in-depth – inside Fmfn, for example:

NGINX load balancing

Start with the basic load balancing configuration.

Edit the default configuration

server {
listen 80 default_server;
listen [::]:80 default_server;

root /var/www/html;

index index.html index.htm index.nginx-debian.html;

server_name _;

location / {
# try_files $uri $uri/ =404;
proxy_pass http://myapp1;


The proxy_pass line sends traffic to the load balancing server group. That group myapp1 needs to be configured in a separate configuration file which I called /etc/nginx/sites-enabled/upstream (it should be placed in the sites-available folder and symlinked to the sites-enabled. The location of your configuration files can be different)

upstream myapp1 {
server localhost:8080;
server localhost:8081;
server localhost:8082;

This part needs to be outside of the server {} block. The easiest way for me was to put this in a separate configuration. I also did not include the http {} section from the configuration on the nginx website, because the http part is in the main server configuration. If you put everything in the config for the website/server (i.e. the sites-available/default file) then you’ll get errors like:

nginx: [emerg] “http” directive is not allowed here

ginx: [emerg] “upstream” directive is not allowed here in /etc/nginx/sites-enabled/default:6

Fix WSUS client that isn’t reporting status

Steps below are: Stopping the services, deleting the registry keys, clearing the SoftwareDistribution folder, starting the services, then forcing the computer to check-in with WSUS. The wuauclt command is apparently no longer used in Windows 10, so the PowerShell command underneath it does the same thing.

net stop bits
net stop wuauserv
reg delete "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate" /v AccountDomainSid /f
reg delete "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate" /v PingID /f
reg delete "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate" /v SusClientId /f
reg delete "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate" /v SusClientIDValidation /f
rd /s /q "%SystemRoot%\SoftwareDistribution"
net start bits
net start wuauserv
wuauclt /resetauthorization /detectnow
PowerShell.exe (New-Object -ComObject Microsoft.Update.AutoUpdate).DetectNow()

Setting up a ZeroTier network

  • Sign up for an account at
  • Create a network (done from the website above)
  • Add clients to the network, and grant/approve access from the web UI (new clients can’t connect until they are specifically given permission)
  • Optional – set up routes.
      • In my example below, I set up one route to a VPS with a public IP address. This way, I can connect to the VPS without going directly over the internet (to use SSH, for example, so it’s not exposed to the internet)
      • On Windows, I had to go into the settings: right click the ZeroTier tray icon, click Show Networks, and check Allow Global IP. This allows ZeroTier to create routes that overlap with the public internet address space. If this box wasn’t checked, the route wouldn’t be added to my PC’s routing table and I wouldn’t be able to connect. See info here (search for allowGlobal)
      • The 20.0/24 network will (or is supposed to) route through a Raspberry Pi to access my home network. I turned on IP forwarding withsudo sysctl -w net.ipv4.ip_forward=1


Annotation 2020-02-09 182427

Blog at

Up ↑