{"id":12319,"date":"2026-03-27T19:24:15","date_gmt":"2026-03-28T00:24:15","guid":{"rendered":"https:\/\/www.rushworth.us\/lisa\/?p=12319"},"modified":"2026-05-27T16:27:15","modified_gmt":"2026-05-27T21:27:15","slug":"verifying-winrm-access-to-capi","status":"publish","type":"post","link":"https:\/\/www.rushworth.us\/lisa\/?p=12319","title":{"rendered":"Verifying WinRM access to CAPI"},"content":{"rendered":"<p>Powershell script that verifies WinRM access and lists certs from CAPI store.<\/p>\n<p># ============================================================================<br \/>\n# User-configurable variables<br \/>\n# ============================================================================<\/p>\n<p>$TargetHost = &#8216;hostname.example.com&#8217;<br \/>\n$TargetLocalComputerName = &#8216;HOSTNAME<br \/>\n$Username = &#8216;localuserid&#8217;<br \/>\n$Password = &#8216;localuserpassword&#8217;<br \/>\n$Port = 5985<\/p>\n<p>Set-StrictMode -Version Latest<br \/>\n$ErrorActionPreference = &#8216;Stop&#8217;<\/p>\n<p># Remote certificate store to inspect.<br \/>\n# Common values:<br \/>\n# Cert:\\LocalMachine\\My<br \/>\n# Cert:\\LocalMachine\\WebHosting<br \/>\n# Cert:\\LocalMachine\\Root<br \/>\n# Cert:\\LocalMachine\\CA<br \/>\n$RemoteCertStorePath = &#8216;Cert:\\LocalMachine\\My&#8217;<\/p>\n<p># Optional subject filter. Leave blank to return everything in the store.<br \/>\n$CertificateSubjectFilter = &#8221;<\/p>\n<p># ============================================================================<br \/>\n# Build local SAM credential<br \/>\n# ============================================================================<\/p>\n<p># Unqualified &#8211; fails<br \/>\n# $QualifiedUsername = $Username<br \/>\n# .\\ &#8211; works<br \/>\n# $QualifiedUsername = &#8216;{0}\\{1}&#8217; -f &#8216;.&#8217;, $Username<br \/>\n# With hostname &#8211; works<br \/>\n$QualifiedUsername = &#8216;{0}\\{1}&#8217; -f $TargetLocalComputerName, $Username<\/p>\n<p>$SecurePassword = ConvertTo-SecureString -String $Password -AsPlainText -Force<br \/>\n$Credential = [System.Management.Automation.PSCredential]::new($QualifiedUsername, $SecurePassword)<\/p>\n<p># ============================================================================<br \/>\n# Check TrustedHosts on the client<br \/>\n# ============================================================================<\/p>\n<p>$trustedHostsValue = (Get-Item WSMan:\\localhost\\Client\\TrustedHosts).Value<br \/>\n$trustedHostEntries = @()<\/p>\n<p>if (-not [string]::IsNullOrWhiteSpace($trustedHostsValue)) {<br \/>\n$trustedHostEntries = $trustedHostsValue -split &#8216;\\s*,\\s*&#8217; | Where-Object {<br \/>\n-not [string]::IsNullOrWhiteSpace($_)<br \/>\n}<br \/>\n}<\/p>\n<p>$trustedHostMatch = $false<br \/>\nforeach ($entry in $trustedHostEntries) {<br \/>\nif ($TargetHost -like $entry -or $TargetLocalComputerName -like $entry) {<br \/>\n$trustedHostMatch = $true<br \/>\nbreak<br \/>\n}<br \/>\n}<\/p>\n<p>Write-Host &#8221;<br \/>\nWrite-Host &#8216;=== Client Context ===&#8217; -ForegroundColor Cyan<br \/>\n[pscustomobject]@{<br \/>\nRunningAs = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name<br \/>\nTargetHost = $TargetHost<br \/>\nPort = $Port<br \/>\nCredentialUser = $Credential.UserName<br \/>\nTrustedHostsValue = $trustedHostsValue<br \/>\nTrustedHostMatched = $trustedHostMatch<br \/>\nRemoteCertStorePath = $RemoteCertStorePath<br \/>\nCertificateSubjectFilter = $CertificateSubjectFilter<br \/>\n} | Format-List<\/p>\n<p>if (-not $trustedHostMatch) {<br \/>\nWrite-Warning &#8220;TrustedHosts does not appear to include $TargetHost or $TargetLocalComputerName. HTTP\/5985 with a local account will usually fail until that is fixed.&#8221;<br \/>\n}<\/p>\n<p># ============================================================================<br \/>\n# Raw TCP check<br \/>\n# ============================================================================<\/p>\n<p>Write-Host &#8221;<br \/>\nWrite-Host &#8216;=== TCP Connectivity Check ===&#8217; -ForegroundColor Cyan<\/p>\n<p>$tcpClient = [System.Net.Sockets.TcpClient]::new()<br \/>\ntry {<br \/>\n$asyncResult = $tcpClient.BeginConnect($TargetHost, $Port, $null, $null)<br \/>\nif (-not $asyncResult.AsyncWaitHandle.WaitOne(3000, $false)) {<br \/>\nthrow &#8220;Timed out connecting to $TargetHost`:$Port&#8221;<br \/>\n}<\/p>\n<p>$null = $tcpClient.EndConnect($asyncResult)<br \/>\nWrite-Host &#8220;TCP connect to $TargetHost`:$Port succeeded.&#8221; -ForegroundColor Green<br \/>\n}<br \/>\ncatch {<br \/>\nWrite-Host &#8220;TCP connect to $TargetHost`:$Port failed: $($_.Exception.Message)&#8221; -ForegroundColor Red<br \/>\nthrow<br \/>\n}<br \/>\nfinally {<br \/>\n$tcpClient.Dispose()<br \/>\n}<\/p>\n<p># ============================================================================<br \/>\n# WinRM over HTTP\/5985 test + remote machine-store certificate inventory<br \/>\n# ============================================================================<\/p>\n<p>Write-Host &#8221;<br \/>\nWrite-Host &#8216;=== WinRM HTTP\/5985 Test ===&#8217; -ForegroundColor Cyan<\/p>\n<p>$session = $null<\/p>\n<p>try {<br \/>\n$session = New-PSSession `<br \/>\n-ComputerName $TargetHost `<br \/>\n-Port $Port `<br \/>\n-Authentication Negotiate `<br \/>\n-Credential $Credential `<br \/>\n-ErrorAction Stop<\/p>\n<p>$remoteResult = Invoke-Command -Session $session -ErrorAction Stop -ArgumentList $RemoteCertStorePath, $CertificateSubjectFilter -ScriptBlock {<br \/>\nparam(<br \/>\n[string]$StorePath,<br \/>\n[string]$SubjectFilter<br \/>\n)<\/p>\n<p>$latfp = $null<br \/>\ntry {<br \/>\n$latfp = Get-ItemPropertyValue `<br \/>\n-Path &#8216;HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\System&#8217; `<br \/>\n-Name &#8216;LocalAccountTokenFilterPolicy&#8217; `<br \/>\n-ErrorAction Stop<br \/>\n}<br \/>\ncatch {<br \/>\n$latfp = $null<br \/>\n}<\/p>\n<p>$identity = [System.Security.Principal.WindowsIdentity]::GetCurrent()<br \/>\n$principal = [System.Security.Principal.WindowsPrincipal]::new($identity)<br \/>\n$isAdmin = $principal.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)<\/p>\n<p>if (-not (Test-Path -Path $StorePath)) {<br \/>\nthrow &#8220;Certificate store path not found: $StorePath&#8221;<br \/>\n}<\/p>\n<p>$certs = Get-ChildItem -Path $StorePath -ErrorAction Stop<\/p>\n<p>if (-not [string]::IsNullOrWhiteSpace($SubjectFilter)) {<br \/>\n$certs = $certs | Where-Object { $_.Subject -like &#8220;*$SubjectFilter*&#8221; }<br \/>\n}<\/p>\n<p>$certInventory = foreach ($cert in $certs | Sort-Object NotAfter, Subject) {<br \/>\n$sanEntries = @()<br \/>\n$dnsNameList = $null<\/p>\n<p>try {<br \/>\n$dnsNameList = $cert.DnsNameList<br \/>\n}<br \/>\ncatch {<br \/>\n$dnsNameList = $null<br \/>\n}<\/p>\n<p>if ($null -ne $dnsNameList) {<br \/>\nforeach ($dnsName in $dnsNameList) {<br \/>\nif ($null -ne $dnsName -and -not [string]::IsNullOrWhiteSpace($dnsName.Unicode)) {<br \/>\n$sanEntries += $dnsName.Unicode<br \/>\n}<br \/>\n}<br \/>\n}<\/p>\n<p>$ekuEntries = @()<br \/>\nforeach ($eku in $cert.EnhancedKeyUsageList) {<br \/>\nif (-not [string]::IsNullOrWhiteSpace($eku.FriendlyName)) {<br \/>\n$ekuEntries += $eku.FriendlyName<br \/>\n}<br \/>\nelseif (-not [string]::IsNullOrWhiteSpace($eku.ObjectId)) {<br \/>\n$ekuEntries += $eku.ObjectId<br \/>\n}<br \/>\n}<\/p>\n<p>[pscustomobject]@{<br \/>\nStorePath = $StorePath<br \/>\nSubject = $cert.Subject<br \/>\nThumbprint = $cert.Thumbprint<br \/>\nNotBefore = $cert.NotBefore<br \/>\nNotAfter = $cert.NotAfter<br \/>\nHasPrivateKey = $cert.HasPrivateKey<br \/>\nIssuer = $cert.Issuer<br \/>\nSerialNumber = $cert.SerialNumber<br \/>\nSignatureAlgorithm = $cert.SignatureAlgorithm.FriendlyName<br \/>\nPublicKeyOid = $cert.PublicKey.Oid.FriendlyName<br \/>\nArchived = $cert.Archived<br \/>\nDnsNames = ($sanEntries -join &#8216;; &#8216;)<br \/>\nEnhancedKeyUsage = ($ekuEntries -join &#8216;; &#8216;)<br \/>\nPSParentPath = $cert.PSParentPath<br \/>\n}<br \/>\n}<\/p>\n<p>[pscustomobject]@{<br \/>\nRemoteComputerName = $env:COMPUTERNAME<br \/>\nRemoteIdentity = $identity.Name<br \/>\nIsAdministrator = $isAdmin<br \/>\nLocalAccountTokenFilterPolicy = $latfp<br \/>\nWinRMServiceStatus = (Get-Service -Name WinRM).Status.ToString()<br \/>\nPSVersion = $PSVersionTable.PSVersion.ToString()<br \/>\nQueriedStorePath = $StorePath<br \/>\nCertificateCount = @($certInventory).Count<br \/>\nCertificates = @($certInventory)<br \/>\n}<br \/>\n}<\/p>\n<p>Write-Host &#8216;WinRM HTTP\/5985 test succeeded.&#8217; -ForegroundColor Green<\/p>\n<p>Write-Host &#8221;<br \/>\nWrite-Host &#8216;=== Remote Probe Data ===&#8217; -ForegroundColor Cyan<br \/>\n[pscustomobject]@{<br \/>\nRemoteComputerName = $remoteResult.RemoteComputerName<br \/>\nRemoteIdentity = $remoteResult.RemoteIdentity<br \/>\nIsAdministrator = $remoteResult.IsAdministrator<br \/>\nLocalAccountTokenFilterPolicy = $remoteResult.LocalAccountTokenFilterPolicy<br \/>\nWinRMServiceStatus = $remoteResult.WinRMServiceStatus<br \/>\nPSVersion = $remoteResult.PSVersion<br \/>\nQueriedStorePath = $remoteResult.QueriedStorePath<br \/>\nCertificateCount = $remoteResult.CertificateCount<br \/>\n} | Format-List<\/p>\n<p>Write-Host &#8221;<br \/>\nWrite-Host &#8220;=== Certificates in $($remoteResult.QueriedStorePath) ===&#8221; -ForegroundColor Cyan<\/p>\n<p>if ($remoteResult.CertificateCount -eq 0) {<br \/>\nWrite-Host &#8216;No certificates matched the requested store\/filter.&#8217; -ForegroundColor Yellow<br \/>\n}<br \/>\nelse {<br \/>\n$remoteResult.Certificates |<br \/>\nSelect-Object Subject, Thumbprint, NotAfter, HasPrivateKey, DnsNames, EnhancedKeyUsage |<br \/>\nFormat-Table -Wrap -AutoSize<br \/>\n}<\/p>\n<p>Write-Host &#8221;<br \/>\nWrite-Host &#8216;=== Computed Summary ===&#8217; -ForegroundColor Cyan<br \/>\n[pscustomobject]@{<br \/>\nHttp5985Success = $true<br \/>\nRemoteIdentity = $remoteResult.RemoteIdentity<br \/>\nIsAdministrator = $remoteResult.IsAdministrator<br \/>\nLocalAccountTokenFilterPolicy = $remoteResult.LocalAccountTokenFilterPolicy<br \/>\nWinRMServiceStatus = $remoteResult.WinRMServiceStatus<br \/>\nQueriedStorePath = $remoteResult.QueriedStorePath<br \/>\nCertificateCount = $remoteResult.CertificateCount<br \/>\n} | Format-List<br \/>\n}<br \/>\ncatch {<br \/>\nWrite-Host &#8220;WinRM HTTP\/5985 test failed: $($_.Exception.Message)&#8221; -ForegroundColor Red<\/p>\n<p>[pscustomobject]@{<br \/>\nHttp5985Success = $false<br \/>\nErrorMessage = $_.Exception.Message<br \/>\nHResult = (&#8216;0x{0:X8}&#8217; -f ($_.Exception.HResult -band 0xffffffff))<br \/>\nFullyQualifiedErrorId = $_.FullyQualifiedErrorId<br \/>\n} | Format-List<br \/>\n}<br \/>\nfinally {<br \/>\nif ($null -ne $session) {<br \/>\nRemove-PSSession -Session $session -ErrorAction SilentlyContinue<br \/>\n}<br \/>\n}<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Powershell script that verifies WinRM access and lists certs from CAPI store. # ============================================================================ # User-configurable variables # ============================================================================ $TargetHost = &#8216;hostname.example.com&#8217; $TargetLocalComputerName = &#8216;HOSTNAME $Username = &#8216;localuserid&#8217; $Password = &#8216;localuserpassword&#8217; $Port = 5985 Set-StrictMode -Version Latest $ErrorActionPreference = &#8216;Stop&#8217; # Remote certificate store to inspect. # Common values: # Cert:\\LocalMachine\\My # Cert:\\LocalMachine\\WebHosting # Cert:\\LocalMachine\\Root &hellip;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1525],"tags":[622,136,2204],"class_list":["post-12319","post","type-post","status-publish","format-standard","hentry","category-windows","tag-powershell","tag-windows","tag-winrm"],"_links":{"self":[{"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/posts\/12319","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=12319"}],"version-history":[{"count":1,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/posts\/12319\/revisions"}],"predecessor-version":[{"id":12320,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=\/wp\/v2\/posts\/12319\/revisions\/12320"}],"wp:attachment":[{"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=12319"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=12319"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.rushworth.us\/lisa\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=12319"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}