Category Archives: PowerShell

Function to download updates from Microsoft Catalog

Last week, I accidentally built a function which downloads update files from Microsoft Update Catalog. What is its real-life application?
Say you are building an OS installation image from scratch, which will then be deployed en masse. Common approach is to integrate all available updates into such image, to increase security and decrease post-installation tasks duration.
For Windows Server 2012 R2 and earlier OSes you have to download and integrate dozens of updates, but you are not sure which ones are required for your installation image (Windows Server 2012 R2 ISO-image has been rebuilt at least three times). The only way to determine which updates to integrate is to install a fresh computer from an ISO-image, connect it to the Internet and check for updates from Microsoft Update.
We can script it as follows:

$SearchResult object will contain a list of updates which your machine requires.

To integrate those updates, you need to receive their .msu or .cab files. Unfortunately there is no way (at least known to me) to extract download links from the $SearchResult object. Here’s where the new Get-WUFileByID function comes to help:
First, you have to get a list of KB IDs from the $SearchResult object:

Then you just pass each one of these to the function and it will download the files:

In the -SearchCriteria parameter, specify a product for which you need to download updates.

As the result, updates will be downloaded to the current catalog (you can redirect them with -DestinationDirectory parameter).
At last, integrrate the updates with help of Add-WindowsPackage cmdlet.

If you do not want to download any files, but wish to receive links only, -LinksOnly switch is here just for that!

The function is covered by tests and available at GitHub. Should you have any questions of suggestions, feel free to leave them in the comments section or raise an issue.

New features for the DNS Synchronization script

Hi guys,
Sorry for the delay: a huge change has happened in my life recently — I moved from Moscow, Russia to Limassol, Cyprus, where I now live and work.
I am still polishing the next part of the “Command-line Infrastructure” series, and today I am here to present you another significant update to the DNS Zones Synchronization script:

  1. Name query modes introduced. Right now, here are two modes:
    • “1” – The script will try to retrieve authoritative nameservers for a zone and then will you them to resolve records in that zone.
    • “0” – The script will use nameservers specified in the config file.

    Specify the required mode for each zone in the new column conveniently named “Mode”. Also, instead of specifying “0”, you can leave the column empty.

  2. This has led to another new feature: From now on, the script supports not only IP addresses as NS servers, but DNS names too. Therefore, “ExtIP” and “IntIP” columns in the configuration file have been renamed to “ExtNS” and “IntNS”.
  3. Even more: you can now leave external nameserver field (ExtNS) empty. In that case, the script will use default operating system DNS servers.

Here is a table for you to better understand how these new features work together:

Mode ExtNS Type Result
0 IP Address Names in the zone resolved using ExtNS IP address.
1 IP Address ExtNS IP address used to find authoritative NSes for the zone.
The first authoritative NS then used to resolve names in the zone.
0 DNS Name Default OS DNS servers used to resolve ExtNS DNS name to an IP address.
This IP address then used to resolve names in the zone.
1 DNS Name Default OS DNS servers used to resolve ExtNS DNS name to an IP address.
This IP address then used to find authoritative NSes for the zone.
The first authoritative NS then used to resolve names in the zone.
0 Empty Names in the zone resolved using default OS DNS servers.
1 Empty Default OS DNS servers used to find authoritative NSes for the zone.
The first authoritative NS then used to resolve names in the zone.

Note, that a query mode does not affect the internal name server at all. Here’s a table for the “IntNS” column as well:

IntNS Type Result
IP Address Requests are sent to this IP address.
DNS Name Default OS DNS servers used to resolve IntNS DNS name to an IP address.
Then requests are sent to this IP address.
Empty An new error is raised. Event ID 52.

As usual, grab the latest release of the script from GitHub!

Small update to my DNS Synchronizer script

I’ve just released a small improvement to my DNS Synchronizer script. The update includes:

  1. Corrected the issue where sub-records of a record prevented that record to be synchronized.
  2. Corrected the way how start and end times are formatted — now they both are formatted equally.
  3. But the most significant one for the end-user, is that the script has been renamed to Sync-DNSZones, in accordance with PowerShell best practices.

If you execute the Get-Verb cmdlet w/o parameters, you’ll see that there is no “Synchronize” verb in the output — that’s why I renamed the script. Do not forget to rename “-NS” an “-REC” files accordingly.

Function to test a date against different conditions

Several weeks ago, my friend Rich Mawdsley asked our Windows Admins Slack team, how to tell if today is the second Tuesday in the month? As we found out, there is no built-in way in PowerShell to determine that. That’s why I present you today a function built specifically to test dates against different conditions. The function can tell you:

  • If the date is a certain weekday in a month. 4th Monday, Second Thursday, last Sunday etc.
  • If the date belongs to a certain quarter of a year.
  • If the date is a start or an end of a quarter.
  • If the date is the last day of a month etc.

Mind, that the output is boolean: the function will not tell you much about the date object, but only does it meet conditions or does it not. It returns $true if the date meets the conditions and $false in all other cases.

Here’s the code of the function, and, of course, you can always find the latest version at my GitHub:

The function covered with tests (you can see the results here), but not completely — I shall certainly improve this in the future. And yes, those tests have already helped me to fix several bugs before the official release 😉

BTW, If you haven’t written tests for your PowerShell code, I found this Introduction to testing with Pester by Jakub Jares very useful — you will start writing tests in Pester before the end of the lecture.

Building Highly-Available Windows Infrastructure: Command-line Style. AD DS. Part 2 — Post-Config

Previous part — Building Highly-Available Windows Infrastructure: Command-line Style. AD DS. Part 1 — Installation

Introduction

In this post we will perform two configurations on our Active Directory Domain Services instance: We’ll define security tiers which later become cornerstones of our privilege delegation principles and we’ll tune domain-joining parameters. Also a quick tweak for the DNS service.


Continue reading Building Highly-Available Windows Infrastructure: Command-line Style. AD DS. Part 2 — Post-Config

Building Highly-Available Windows Infrastructure: Command-line Style. AD DS. Part 1 — Installation

Introduction

Up to this day, Active Directory Domain Services (AD DS) has been the core of the Windows infrastructure. With each release of Windows Server, AD DS receives new features while keeping great backward compatibility. Windows Server 2016 brings following enhancements to AD DS:

In this blog we shall install the corner stone of our future infrastructure: a highly-available AD DS instance of two domain controllers. Our AD DS layout is going to be quite simple: two writable domain controllers in a single site.


Continue reading Building Highly-Available Windows Infrastructure: Command-line Style. AD DS. Part 1 — Installation

Building Highly-Available Windows Infrastructure: Command-line Style

Several months ago Windows Server 2016 was released. With this release Microsoft has made two significant changes in Windows Server installation options:

  • Nano Server was introduced
  • Server with a GUI now includes desktop experience features (it is even called “Server with Desktop Experience”) and there is no supported way to remove them. This should force IT Administrators to deploy Server Core more broadly.

Looks like now is a good time to stop thinking about Windows Server as a GUI based system and pivot your management approach to be more command-line.
This post is the first in a series of how to build your own highly-available Windows infrastructure using just PowerShell and some other command-line tools. I plan to discuss the following components:

  • Active Directory Domain Services,
  • Active Directory Certificate Services,
  • Desired State Configuration,
  • Key Management Services,
  • DHCP,
  • SCDPM,
  • SCCM,
  • Exchange Server,
  • And, possibly, S4B Server, as well.

I am not able to deploy Hyper-V hosts yet, as all my infrastructure is purely virtual and the host machine, sadly, is running Windows Server 2012 R2 and currently it is impossible for me to upgrade it.

All PowerShell code will not use any hardcoded values. Instead, at the beginning of each post, I shall include a set of variables which will allow you to easily recreate the infrastructure in your environment w/o any change in the code.

The first part is already here! Building Highly-Available Windows Infrastructure: Command-line Style. AD DS. Part 1 — Installation

Huge refactoring of Synchronize-DNSZones.ps1

Today I finished huge refactoring of my Synchronize-DNSZones script (see more about it here). The main reason to refactor was to introduce a support to synchronize zone-level records. To efficiently achieve this, I converted a huge pile of code into several smaller functions. I also improved code readability by PS 3.0 standards (apparently, it is also StrictMode-compatible now).
I improved error handling by introducing 3 new error events:
55 – DNS-zone creation is not yet supported. (And I don’t think I’ll ever support it)
72 – Function New-DnsRecord failed.
82 – Cannot import DNSClient PowerShell module.

I finally replaces unapproved verbs in function names to approved ones (see Get-Verb). I shall change the name of the script itself later.
Fixed an issue when Receive-DnsData sometimes returns empty response and.
Fixed typos and incorrect error handling and slightly enhanced comments.
And I also added forgotten definition of $SMTPCc variable.

In the future I plan to add ShouldProcess support (WhatIf).

Pull-requests / issues are welcome!

Split-brain DNS Synchronizer

The latest version of the script available at GitHub.

Many companies use the same domain name for both internal and external servers hosting. When an internal domain name is a name of AD DS domain, and internal users must access some of the servers by their external IP-addresses, the problem arises: somehow all these external names must exist in the internal zone and the record information in these internal records must be in correspondence with the external ones. There are several possible solutions to resolve such situation:

1. Blindly forward all external requests to AD DS controllers. In this case, domain controllers are the primary name servers for the zone.

Pros:

  • Single point of management.
  • No new software on domain controllers required.

Cons:

  • You cannot point internal and external users to different hosts for the same DNS-record.
  • Requires to allow external users access to internal servers, which might be impossible due to security policies. Possible exposure of internal infrastructure to an external malicious user.
2. Have two separated set of DNS-servers for internal and external zones.

Pros:

  • You can point internal and external users to different hosts for the same DNS-record.
  • External users do not access internal servers.
  • No new software on domain controllers required.

Cons:

  • Two different points of management. DNS-records may become outdated.
3. Use DNS policies – the new Windows Server 2016 functionality.

https://blogs.technet.microsoft.com/teamdhcp/2015/08/31/split-brain-dns-in-active-directory-environment-using-dns-policies/

Pros:

  • Single point of management.
  • You can point internal and external users to different hosts for the same DNS-record.

Cons:

  • Requires domain controllers migration to the latest software, which is not possible for some organizations.
  • Requires to allow external users access to internal servers, which might be impossible due to security policies. Possible exposure of internal infrastructure to an external malicious user.

 

Currently, I prefer the second method, with two sets of DNS servers. But in that case we have another challenge: How to ensure that all DNS-records, which must point to the same location for both external and internal users, are in sync?
Continue reading Split-brain DNS Synchronizer