Monthly Archive

Categories

Test DNS servers

Had a recent comment about testing DNS servers which got me thinking how do I test DNS servers.

I decided I wanted to get the DNS server address from the client, ping the DNS server to test network connectivity and test if DNS was up and working. The current result is this:

function test-dnsserver {
[CmdletBinding()]

## get-dns server address
$addresses = Get-DnsClientServerAddress -AddressFamily IPv4 -InterfaceAlias LAN |
Select-Object -ExpandProperty ServerAddresses

## test servers
foreach ($address in $addresses){
$resolved = $false
$ping = Test-Connection -TargetName $address -Quiet -Count 1
$server = Resolve-DnsName -Name $address -Server $address

if ($server.NameHost) {
$serverName = $server.NameHost
$resolved = $true
}
else {
$serverName = 'DNS unreachable'
}

$props = [ordered]@{
DNSserverName = $serverName
DNSserverIP = $address
Pingable = $ping
Resolved = $resolved
}

New-Object -TypeName PSObject -Property $props
}
}

 

I always set my network interface alias to LAN so you may want to change that or even make it a parameter.

 

Use Get-DNSCleintServerAddress from the DNSclient module to get the DNS server addresses.

 

Loop through the addresses – you could make this a single pipeline if you wanted rather than using foreach loop.

 

Run a ping test using Test-Connection. the version of Test-Connection in PowerShell core is truly horrible as it prints a whole load of stuff to screen even in quiet mode. One of these days I need to write a ping type function that actually works like I want – similar to the Windows PowerShell Test-Connection.

 

Use Resolve-DNSname, again from the DNSclient module, to resolve the server address on the DNS server. If thsi works you should get the DNS server name back in the NameHost property even if you don’t have a reverses lookup zone! Change resolved to $true in this case.

 

The results give you the DNS server name, IP address, if its ping able and if it can perform DNS resolution. If you can’t ping it then either the servers down or you have network problems. If it can’t perform the resolution then DNS is down or it doesn’t have a record for itself. Further investigation is then required.

 

Test isn’t perfect but it does give you a reasonable idea of where problems might be.

Windows Terminal

Microsoft have released the first preview of the new Windows Terminal to the Windows store - https://devblogs.microsoft.com/commandline/windows-terminal-microsoft-store-preview-release/

 

Its currently only available for Windows 10 v18362 or later.

 

The terminal is a replacement for the very elderly Windows console – used for command prompt and PowerShell.

 

Some improvements over the old console include multiple tabs, Unicode and UTF-8 support and custom themes, styles and configurations.

 

Be interesting to see if its actually a good replacement or just makes life more complicated. I’ll post more after some experimentation.

PowerShell 7 roadmap

It was recently announced that the next version of PowerShell core will be 7.0 not 6.3. The PowerShell 7 roadmap is available at https://devblogs.microsoft.com/powershell/powershell-7-road-map/

 

The highlights are PowerShell 7 eventually replacing Windows PowerShell but I expect that’ll be 7.x rather than 7.0 as the mechanisms to update PowerShell aren’t in place. The Windows PowerShell modules that currently don’t work with PowerShell core will be updated to work directly in core – no more WindowsCompatibility module. Expect this to happen only on latest Windows 10 and windows server editions.

 

The PowerShell support life cycle changes to match .NET core

 

PowerShell 7 to use .NET Core 3.0 which will bring back some of the missing APIs including WPF and WinForms meaning Out-GridView will return on Windows

 

Three features are explicitly mentioned; – Secure Credentials management, Looging off the box and new version notifications.

 

Requested features are listed of which the most useful is probably Foreach-Object parallel as a (partial) replacement for workflows.

 

The opportunity is here for you to comment on RFCs and provide feedback to the PowerShell team. This is your chance to help shape PowerShell 7.

Start Jobs with &

You usually start background jobs using Start-Job. Now you can start jobs with &. As of PowerShell v6.0 putting & at the end of a pipeline causes the pipeline to be run as a PowerShell job, for instance this pipeline:

PS> Get-Process | Sort-Object -Property CPU -Top 5

 

Is run as a background job by adding & to the end of the pipeline:

PS> Get-Process | Sort-Object -Property CPU -Top 5 &

 

When a pipeline is backgrounded, a job object is returned. Once the pipeline is running as a job, all of the standard job cmdlets can be used to manage the job. Variables (ignoring process-specific variables) used in the pipeline are automatically copied to the job so

Copy-Item -Path $path -Destination $dest &

 

just works without the need for the $using scope modifier or an argument list.

I recommend this technique for interactive working but that you use Start-Job in your scripts for more control (such as naming the job).

Install-Module and Update-Module Scope parameter

I’ve written a couple of times this year on the problems around the PowerShellGet module and the Scope (Allusers or CurrentUsers). The situation is a lot easier now that Install-Module and Update-Module Scope parameter is available.

Install-Module has always had a Scope parameter.

Update-Module has a Scope parameter as of PowerShell v6.2.1 and Powershell v7.0 preview 1.

 

I’ve changed mu profile to define the Scope parameter for both cmdlets as a default parameter:

$PSDefaultParameterValues = @{'Install-Module:Scope'='AllUsers'; 'Update-Module:Scope'='AllUsers'}

 

The rules for Install-Module default scopes seem to have changed with them now being:

When no Scope is defined, the default is set based on the PowerShellGet version.

In PowerShellGet versions 2.0.0 and above, the default is CurrentUser, which does not require elevation for install.

In PowerShellGet 1.x versions, the default is AllUsers, which requires elevation for install.

 

The documentation hasn’t caught up to Update-Module but past experience suggests it follows the same rules.

 

This is a good change as it gives back control of where the user puts the module, Too much software these days forces the developer’s assumptions on the user with no option to override. Its good to get the control back

Get-Date -UFormat

The Get-Date -UFormat parameter formats the date using Unix format. The full list of format specifiers are in the Notes section of the Get-Date help file.

Some examples are:

PS> Get-Date -UFormat '%Y-%m-%d %H:%M%:%S%Z'
2019-05-27 20:40:11+01

 

4 digit year – two digit month and day. Hour in 24 hour format and minutes and seconds and finally time zone as offset from GMT

 

Date in locale format

PS> Get-Date -UFormat %x
05/27/19

though it shows a US format for a UK locale?

 

PS> Get-Date -UFormat '%A %d %B %Y'
Monday 27 May 2019

day of week – day – Month (full name) 4 digit year.

 

Between the Format parameter and the UFormat parameter you should be able to get the date information into any format you require

Get-Date –Format

Get-Date –Format enables you to control the formatting of the datetime object returned by the cmdlet.

A standard call to get date returns:

PS> Get-Date

27 May 2019 12:36:47

 

The –Format parameter takes a value from the DateTimeFormatInfo class - https://docs.microsoft.com/en-us/dotnet/api/system.globalization.datetimeformatinfo?view=netframework-4.8 – to specify how you want the information to be formatted.

 

For instance:

Short and long forms of the date with no time

PS> Get-Date -Format d
27/05/2019
PS> Get-Date -Format D
27 May 2019

 

Full date and short or long time

PS> Get-Date -Format f
27 May 2019 12:48
PS> Get-Date -Format F
27 May 2019 12:48:38

 

No year or time

PS> Get-Date -Format m
27 May
PS> Get-Date -Format M
27 May

 

RFC1123 compliant

PS> Get-Date -Format R
Mon, 27 May 2019 12:50:07 GMT
PS> Get-Date -Format r
Mon, 27 May 2019 12:50:10 GMT

 

Sortable

PS> Get-Date -Format s
2019-05-27T12:50:45

 

Short and long time only

PS> Get-Date -Format t
12:51
PS> Get-Date -Format T
12:51:14

 

Sortable Universal time

PS> Get-Date -Format u
2019-05-27 12:51:55Z

Z refers to the time zone

 

Specify day month year format

PS> Get-Date -Format 'dd/MM/yyyy'
27/05/2019

Exclusive OR

PowerShell has a number of logical operators - -  -and, –or, –not (or !). One I’ve really thought about is the exclusive OR operator –xor.

With a standard –or operator the result is TRUE if one of the statements is TRUE

PS> ('a' -eq 'A') -or ('a' -eq 'z')
True

 

The standard –or operator is also TRUE if both statements are true

PS> ('a' -eq 'A') -or ('Z' -eq 'z')
True

 

The exclusive OR is only TRUE when one of the statements is TRUE and the other is FALSE. So this returns TRUE

PS> ('a' -eq 'A') -xor ('a' -eq 'z')
True

 

But when both statements are TRUE it returns FALSE

PS> ('a' -eq 'A') -xor ('Z' -eq 'z')
False

 

The exclusive OR seems like  bit of an oddity to me.

 

PowerShell has a bitwise xor operator  -- -bxor but outside of that I’m struggling to find a use for –xor. Certainly as an admin I can’t think of a situation where I’d use it.

 

Just out curiosity have you used –xor and if so how?

Useful constants

PowerShell provides easy access to some useful constants. I often see people calculating these values rather than using the constants.

PowerShell recognises kb, mb, gb, tb and pb for kilobyte, megabyte, gigabyte, terabyte and petabyte respectively. You can use them like this:

PS> 1kb; 1mb; 1gb, 1tb, 1pb
1024
1048576
1073741824
1099511627776
1125899906842624

 

Don’t leave a space between the value and the constant.

You can use them in calculations:

PS> 7247437567256292 / 1gb
6749702.21450207
PS> 7247437567256292 / 1tb
6591.50606884968
PS> 7247437567256292 / 1pb
6.43701764536101

 

Fractional values are allowed:

PS> 27.457gb
29481729261.568

 

You can use upper case or lower case to denote the constant

PS> 27.457gb
29481729261.568
PS> 27.457GB
29481729261.568

 

Next time you need to work with megabytes or other common constants don’t calculate them use the constants in PowerShell

Articles published in 2019

I’ve had the following articles published in 2019

https://searchwindowsserver.techtarget.com/tutorial/Set-up-users-with-key-PowerShell-Active-Directory-commands

https://searchwindowsserver.techtarget.com/feature/Editing-content-with-Windows-PowerShell

https://searchwindowsserver.techtarget.com/tip/Windows-Compatibility-module-expands-PowerShell-Core-reach

 

Enjoy