Public/Get-WinClatConfiguration.ps1
|
Function Get-WinClatConfiguration { <# .SYNOPSIS Returns global Windows CLAT (WinCLAT) configuration. .DESCRIPTION Wraps 'netsh.exe interface clat show global' and returns the output as WinClat.Configuration objects. Runs locally or against one or more remote computers in parallel. Does not require elevation. Every computer produces at least one object. Computers that cannot be reached return Status Unreachable, computers without the WinCLAT feature return Status FeatureNotAvailable with their OS build, and Windows Server computers without it return Status NotSupported, because Microsoft delivers WinCLAT to client editions only. WinCLAT is generally available on Windows 11 version 25H2 build 26200.9550 and later. PolicyControlled lists the settings that Group Policy controls, as a comma-separated string such as 'Permit, Pref64FromRA'. CollectedAtUtc records when netsh ran on the target, in UTC. Remote computers must have WinRM enabled, typically through Group Policy. Roaming devices may be offline at run time. Each remote computer is first checked on TCP 5985 (WinRM over HTTP); one that does not answer within 2 seconds, or whose name does not resolve, is returned as Unreachable at once instead of after a WinRM timeout. Failures are not written as errors: every computer returns its result with a Status and a Message that explains it, and when a run for several computers has any computer that did not complete, one warning at the end gives the count. To list them, filter the results, for example with Where-Object -FilterScript { $_.Status -ne 'Success' }. .PARAMETER Store Configuration store to return. Active is the effective configuration, Persistent is the local configuration (which Group Policy may override), and Both returns one object for each. .PARAMETER ComputerName One or more computers to query. Accepts pipeline input by value and by property name, including objects from Get-ADComputer and Get-ADObject; DNSHostName is preferred over Name. Blank values and values beginning with '#' are ignored, so Get-Content output can be piped directly. Defaults to the local computer. .PARAMETER Credential Credentials used to connect to remote computers. Not used for the local computer. .PARAMETER ThrottleLimit Maximum number of concurrent remote connections. The default is 32. .INPUTS System.String. Computer names. System.Management.Automation.PSObject. Objects with a DNSHostName, ComputerName, Name, or CN property, such as those from Get-ADComputer and Get-ADObject. .OUTPUTS WinClat.Configuration. When a run returns exactly one result, it also carries the type name WinClat.Configuration#Single, which selects a list view instead of the default table. .EXAMPLE Get-WinClatConfiguration -Store Both Returns the active and persistent configuration of the local computer. .EXAMPLE Get-Content -Path .\clients.txt | Get-WinClatConfiguration Returns the active configuration of each computer listed in clients.txt. .EXAMPLE Get-ADComputer -Filter * -SearchBase 'OU=Windows Clients,DC=lab,DC=richardhicks,DC=net' | Get-WinClatConfiguration | Export-Csv -Path .\winclat.csv -NoTypeInformation Exports the active configuration of every computer in the OU to a CSV file. .EXAMPLE Get-Content -Path .\clients.txt | Get-WinClatConfiguration | Where-Object -FilterScript { $_.Status -ne 'Unreachable' } Returns the configuration of the computers in clients.txt that could be reached, leaving out the Unreachable rows. The warning at the end still counts the computers that were unreachable. .LINK https://learn.microsoft.com/windows-server/administration/windows-commands/netsh .NOTES Version: 1.0.0 Creation Date: October 28, 2026 Last Updated: October 28, 2026 Author: Richard Hicks Organization: Richard M. Hicks Consulting, Inc. Contact: rich@richardhicks.com Website: https://www.richardhicks.com/ See docs/DESIGN.md, section 7.1. #> [CmdletBinding(PositionalBinding = $false)] [OutputType('WinClat.Configuration')] Param ( [ValidateSet('Active', 'Persistent', 'Both')] [string]$Store = 'Active', [Parameter(Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)] [Alias('DNSHostName', 'CN', 'Name')] [string[]]$ComputerName = $env:COMPUTERNAME, [PSCredential]$Credential, [ValidateRange(1, 1024)] [int]$ThrottleLimit = 32 ) Begin { $Targets = New-Object -TypeName 'System.Collections.Generic.List[string]' } Process { # Read $_ only for pipeline input; otherwise it may be an outer ForEach-Object variable. $PipelineObject = $null If ($MyInvocation.ExpectingInput) { $PipelineObject = $_ } ForEach ($Name in @(Get-WinClatTargetName -InputObject $PipelineObject -ComputerName $ComputerName -Cmdlet $PSCmdlet)) { $Targets.Add($Name) } } End { $NewFailure = { Param ($Name, $Status, $Message) ConvertTo-WinClatConfiguration -ComputerName $Name -Status $Status -Message $Message -CollectedAtUtc (Get-Date).ToUniversalTime() } $RemoteParameters = @{ ComputerName = $Targets.ToArray() ScriptBlock = Get-WinClatConfigurationScript ArgumentList = @($Store.ToLowerInvariant()) ThrottleLimit = $ThrottleLimit NewFailureObject = $NewFailure Cmdlet = $PSCmdlet } If ($Credential) { $RemoteParameters['Credential'] = $Credential } # One summary warning at the end instead of an error per computer (DESIGN.md, section 4.6). For a single computer the # results are held, so exactly one is shown as a list and several as a table (section 6); fleet results still stream. $Tally = New-WinClatTally -ComputerName $Targets.ToArray() Invoke-WinClatRemote @RemoteParameters | Measure-WinClatResult -Tally $Tally Complete-WinClatResult -Tally $Tally Write-WinClatFailureSummary -Tally $Tally -Action 'queried' -Cmdlet $PSCmdlet } } |