Powershell Script to email you your lunch break

#Sets $theTime variable to the current time.
$lunchStarted = Get-Date
$lunchStartsUKDate = $lunchStarted.ToLongDateString()
$lunchStartsUKTime = $lunchStarted.ToShortTimeString()

$HOST.UI.RawUI.ReadKey(“NoEcho,IncludeKeyDown”) | OUT-NULL

$lunchEnded = Get-Date
$lunchEndsUKDate = $lunchEnded.ToLongDateString()
$lunchEndsUKTime = $lunchEnded.ToShortTimeString()

#Define hub transport server
$smtpServer = “smtp server”

#Define email sender and recipient
$sender = “sender”
$recipient = “recipient”

#Define email subject and body
$msgSubject = “Lunch!”
$msgBody_Text = “You went out to lunch at $lunchStartsUKDate $lunchStartsUKTime, and came back at $lunchEndsUKDate $lunchEndsUKTime”

#Send it
Send-MailMessage -to $recipient -from $sender -subject $msgSubject -body $msgBody_text -smtpserver $smtpServer

DNS oddities in Windows 10

We’ve been having a lot of issues recently with Windows 10 devices not updating DNS properly when DHCP servers are set to do the dynamic updating on behalf of the client.

There a LOT of advice out there- adding servers to the builtin DNSUpdateProxy group, fiddling about with netsh etc. The long and the short of it from my perspective is don’t waste time with these as I couldn’t get them to work, just switch off dynamic updating on the DHCP server and let clients register themselves.

Whatever the actual issue, this seems to be new to Windows 10 and although it could well be related to having an older domain functional level etc, this isn’t something I can fix easily because most DCs are still on 2008R2 and they’re spread across a wide geographical area so I can’t just upgrade them. Changing the way DNS is updated seems to have fixed the problem so that’s fine with me, and is a much faster solution than systematically trying the myriad suggestions out there.

Group policy oddities

Explanation: a lot of junk has been added to our Default Domain Policy & Default Domain Controller Policy. I was hoping to reset them with dcgpofix.exe. But obviously the first thing I did was (a) print them out, and (b) back them up. Obviously.

Except I couldn’t back up the DDC policy. Have 83 GPOs, and could only back up 82 successfully. Brilliantly, the error was “Backup of GPO failed. Error [Invalid pointer]”, which is hugely helpful.

This blog post – https://moodjbow.wordpress.com/2015/10/28/cannot-backup-gpo-error-invalid-pointer/ – got me pointed quite a long way in the right direction.

  1. Firstly, it’s the only place that seems to mention the fact that the group policy logging keys have to be DWORDs.
  2. Secondly it mentions that the cause could be erroneous user accounts/ SIDs (unlike https://support.microsoft.com/en-us/help/3005420/gpmc-backup-of-a-gpo-fails-together-with-an-invalid-pointer-error-mess which bangs on about DNS- my fix had nothing to do with DNS).
  3. Thirdly, the last line on moodjbow – “Search for lines including [WARNING] and google around for similar symptoms” – was precisely what led me to fix the issue once I’d got gpmgmt.log up and running.

The gpmgmt.log was reporting a couple of unresolvable SIDs and after hunting around pointlessly for SID convertion tools, I thought I’d have a dig about in some BUILTIN groups and lo and behold, there was a dodgy, legacy user in BUILTIN\Administrators. I deleted this, re-ran the backup and one of the warnings disappeared (tho’ the user has reappeared in BUILTIN\Administrators).

There was still one warning block left, which was:

“[3258.150c] 11/30/2017 13:57:30:243  [VERBOSE] ResolveTrustee(): Resolving account <DOMAIN\user> User Name <(null)>.
[3258.150c] 11/30/2017 13:57:30:259  [VERBOSE] ResolveTrustee(): Resolving account <S-1-5-21-1777476757-2052732148-4547331-26365> Domain Controller <(null)>.
[3258.150c] 11/30/2017 13:57:30:275  [VERBOSE] ResolveTrustee(): Account name is <user>
[3258.150c] 11/30/2017 13:57:30:290  [VERBOSE] CGPMBackupData::AddKnownSecurityPrincipal: SecurityPrincipal Added is DOMAIN\(null)
[3258.150c] 11/30/2017 13:57:30:306  [WARNING] CGPMBackupData::AddKnownSecurityPrincipal: GetFullAcctNameEx Failed with 0x80004003
[3258.150c] 11/30/2017 13:57:30:306  [WARNING] CGPMBackupData::PutSID: AddKnownSecurityPrincipal of S-1-5-21-1777476757-2052732148-4547331-26365 Failed with 0x80004003
[3258.150c] 11/30/2017 13:57:30:322  [WARNING] ProcessNameList: PutSID failed”

The user account in question had been disabled for ages withouth causing any apparent problems, so I just deleted it and the backup worked.

Time to fix? Actual remedial work was about 10 minutes, time spent digging around through Bing and Google was about 4 hours.


Having had this vulnerability flagged to us, we needed to figure out a way to run the detection tool against our estate. This is tricky because the tool is pretty much stand-alone; it can’t natively write to a centralised file or anything, so each PC generates its own isolated log file.

Having determined it’s quite hard to write the log files to a centralised store, I went old skool & set up a group policy that runs this batch file:

md C:\Support
md C:\Support\Scripts
copy \\domain.fqdn\netlogon\INTEL-SA-00086\INTEL-SA-00086.ps1 C:\Support\Scripts
%SYSTEMROOT%\System32\WindowsPowerShell\v1.0\powershell.exe -File C:\Support\Scripts\INTEL-SA-00086.ps1

I’ve got this group policy attached to a WMI filter that negates Server OSs but it’s not necessary- servers can be just as vulnerable, but we did those manually and I’m reluctant to have junk copied automatically to all the servers without intervention.

Anyway, this creates a couple of folders at the root of C:\, copies a PowerShell script and runs it. The script is:

$result = Test-Path C:\Support\Intel\INTEL-SA-00086\$env:ComputerName.log

If($result -eq $false)
New-Item -Path "C:\" -Name "Support" -ItemType "directory" -ErrorAction SilentlyContinue
New-Item -Path "C:\Support" -Name "Intel" -ItemType "directory" -ErrorAction SilentlyContinue

Copy-Item -Path \\domain.fqdn\netlogon\INTEL-SA-00086 -Destination C:\Support\Intel -recurse -ErrorAction SilentlyContinue

Set-Location C:\Support\Intel\INTEL-SA-00086\DiscoveryTool

.\Intel-SA-00086-console.exe > C:\Support\Intel\INTEL-SA-00086\$env:ComputerName.log

$logFile = Get-Content C:\Support\Intel\INTEL-SA-00086\$env:ComputerName.log

$analysis = $logFile | Select-String "Based"

#Define hub transport server
$smtp_server = "smtp.server"

#Define email sender and recipient
$sender = "INTEL-SA-00086@primary.mail.domain"
$recipient = "user_1@primary.mail.domain","optional_user_2@primary.mail.domain"

#Define email subject and body
$msg_subject = "Analysis result of the SA-00086 detection tool on $env:ComputerName"
$msg_body_text = "Analysis result for $env:ComputerName is: $analysis`n`nThe script that generated this email is C:\Support\Intel\INTEL-SA-00086\INTEL-SA-00086.ps1"

#Send it
Send-MailMessage -to $recipient -from $sender -subject $msg_subject -body $msg_body_text -smtpserver $smtp_server -attachments C:\Support\Intel\INTEL-SA-00086\$env:ComputerName.log

And I’ve just noticed that the script uses PowerShell to create the same 2 folders the .cmd file creates. Oops. Anyway, the PS script:
* Initially checks to see if the log file it creates already exists;
* If it does, the script stops to avoid repeatedly sending the same data;
* It then creates a folder structure & copies the SA-00086 tool from a central location (netlogon is always handy) into this structure;
* It runs the tool & sends the output to a log file in the folder structure created above;
* It uses PowerShell to extract the contents of the log file, and identifies the string containing the analysis (vulnerable/ not vulnerable/ unsure);
* It puts this string into the body of the email & attaches the log file for completeness, then sends the email;
* The script uses $env:ComputerName throughout so each logfile is identified by the unique PC name;

That’s it- any collation of the data has to be done manually but you should end up with a vulnerability report from every device on your network, just once (hopefully).

WSUS vs Windows 7/ Windows 8.1 client issues

We’ve recently needed to be a bit more rigorous about using WSUS, so I started off on our servers and found out that if you go with “Scheduled Installs”, what this means is that any given server can reboot pretty much when it likes with up to 30 minutes grace.

This was no good at all, so I started using a PowerShell script to do the WSUS side of things, then used a server to run scheduled tasks against a group of servers at a time. This meant that we could reboot the servers when we liked, which is around 04:00.

This was all ticking along nicely, so we opened this out to a select number of clients- mix of Windows 7 Pro SP1 and Windows 8.1 Pro. Very little happened. PCs didn’t get patched, running WSUS through the GUI resulted in the progress bar looping, PowerShell didn’t work, the Event Viewer only displayed errors and WSUS itself complained the PCs hadn’t reported for a long time, or maybe not at all.

After a week of fiddling about with the Windows Update client, deleting registry keys, deleting WindowsUpdate.log etc etc, turns out it seems there are 2 KB articles- KB3138612 & KN3138615- that appear to be critical to getting WSUS working on clients. These KBs relate to “updates for Windows Update” dated March 2016.

The long and the short of it is that it appears the best way to get Windows 7 & 8.1 working is to start from scratch: reinstall Windows from a DVD and then immediately install the relevant KB .msu file.

I tried pointing freshly-built clients at WSUS (before installing the KB) and they either just looped (Windows 8.1) or told you to install an update to Windows Update (Windows 7). This build under Windows 8.1 wouldn’t even talk to WSUS until I’d installed the KB, and I assumed the Windows 7 Windows Update Client Update was the right KB article, although it didn’t say.

I now have 3 new Windows 8.1 images: the OS by itself, the OS with KB3138615 and the OS with all available updates from WSUS. I’m doing the same thing for Windows 7. Unfortunately, this means our existing SCCM images are “fine” in that they’re patched, but it looks like they can’t talk to WSUS so our choice is either to talk to Microsoft to fix this, or re-image all our PCs with the new images. This isn’t my call, but is seriously annoying to find out when we’ve just gone around using SCCM to apply images to PCs whic won’t actually update on a day-to-day basis.

Microsoft KB3124557: MS16-010: Security update in Microsoft Exchange Server to address spoofing: January 12, 2016

First thing to be aware of is that this update definitely does come down through WSUS, which was my first mistake (I’m so used to Exchange updates being full-blown CUxx-style, download-the-entire-ISO-again that I didn’t expect this to show up).

We have a 3-node DAG, and of course I hit “install all updates” on all 3 nodes. Meaning Exchange services got disabled (and I mean disabled. not just stopped) on all nodes. My thinking for this was that as Node 1 wasn’t managing any mailbox databases, I could patch it (not realising it had an Exchange update), reboot it, move some DBs, then reboot the other two nodes one at a time, juggling DBs as necessary.

Once I saw what was going on, I cancelled the update which is a bad idea, because it neither continued to install the patch nor rolled back the patch by re-enabling and starting Exchange services. So after cancellation, I had 3 nodes, none of which had the patch and all of which had Exchange disabled.

At this point, my “bads” were a) I should have checked whether the updates included anything for Exchange and b) not cancelled the update jobs.

To make matters worse, I’ve got 2 mailboxes but they’re both in the same mailbox database, and this database was on mounted on Node 3 which still had all of its services disabled. So when I logged on to ECP with my admin account, all I got was a blank screen.

After raising an incident, and then getting a phone call from Microsoft (http://support.microsoft.com/oas) it turns out that basically all I had to do was switch all the services to automatic on Node 3, and then start them. Suddenly, I could get to ECP, my mailboxes were accessible etc etc (and yes, I should have been using PowerShell, not ECP).

DNS entry problems on a DC with attached iSCSI

We’ve recently set up a new DC with some iSCSI storage attached- single site, so the DC is providing DC & file storage.

In DNS, the LAN and iSCSI entries were showing up which was annoying, as pinging generally didn’t work because it would try to find the iSCSI network.

In short, you don’t need to mess around with any network connections or fiddle about in the registry- use method 2 from


Just stop the DNS on the DC listening on any port other than the LAN- including an IPv6 interfaces (in our case at any rate).