MDT2013任务序列执行WinRM HTTPS配置PowerShell脚本时的UNC路径异常解决咨询
MDT2013任务序列执行WinRM HTTPS配置PowerShell脚本时的UNC路径异常解决咨询
针对你遇到的问题——MDT任务序列执行WinRM HTTPS配置脚本时,功能正常但日志总是抛出UNC路径不支持的错误,我来给你分析原因并提供可行的解决方案:
问题根源
这个错误的核心原因是:MDT任务序列执行脚本时,当前工作目录是UNC网络路径(比如你日志里的\\1.2.3.4\D$\Scripts),而你脚本里用Invoke-Expression调用winrm命令时,winrm底层会依赖CMD环境,CMD本身不支持将UNC路径作为当前工作目录,因此会抛出这些警告/错误日志——虽然不影响最终功能,但确实会干扰日志排查。
解决方案
我提供两种思路,你可以根据实际场景选择:
方案1:执行脚本前切换到本地目录
在脚本最开头添加切换工作目录的代码,把当前路径从UNC切换到本地目录(比如系统临时目录),这样CMD调用时就不会触发UNC路径限制:
# 切换到本地临时目录,规避UNC路径限制 $localWorkingDir = "C:\Windows\Temp" if (-not (Test-Path -Path $localWorkingDir)) { New-Item -ItemType Directory -Path $localWorkingDir | Out-Null } Set-Location -Path $localWorkingDir
方案2:替换winrm命令为PowerShell原生WSMan cmdlet
完全抛弃winrm命令行工具,改用PowerShell自带的WSMan模块cmdlet,全程在PowerShell环境执行,从根源上避免依赖CMD的问题,同时更符合PowerShell最佳实践。
下面是修改后的完整优化脚本,我已经替换了winrm相关调用,同时优化了证书查找和错误处理逻辑:
Function CheckWinRMHTTPSConfiguration{ [CmdletBinding()] param( [Parameter(Mandatory=$False)][System.Boolean]$isWinrmHttpsConfigured = $false ) # 用PowerShell原生方式检查HTTPS监听器 $state_of_WinrmHttps = Get-WSManInstance -ResourceURI winrm/config/Listener -ErrorAction SilentlyContinue | Where-Object {$_.Transport -eq "HTTPS"} $isWinrmHttpsConfigured = [bool]$state_of_WinrmHttps return $isWinrmHttpsConfigured } Function ConfigureWinRMwithPROJECTAACertificate_https{ $FQDN_of_LocalMachine = ([System.Net.Dns]::GetHostByName($env:computerName).Hostname) # 提前过滤符合模板的证书,减少后续判断逻辑 $Cert_output = Get-ChildItem Cert:\LocalMachine\My | Select-Object @{N="Template";Expression={ $ext = $_.Extensions | Where-Object {$_.oid.FriendlyName -eq "Certificate Template Information"} if ($ext) { $ext.Format(0) -replace "(.+)?=(.+)\((.+)?", '$2' } }}, @{N="Subject";Expression={$_.SubjectName.Name}}, Thumbprint | Where-Object {$_.Template -eq "ORGANIZATIONTEMPLATENAMEHERE"} if (-not $Cert_output) { Write-Host "No ORGANIZATIONTEMPLATENAMEHERE certificate available on $FQDN_of_LocalMachine" } elseif ($Cert_output.Count -gt 1) { Write-Host "Multiple ORGANIZATIONTEMPLATENAMEHERE certificates found on $FQDN_of_LocalMachine. Skipping configuration…" } else { $Thumbprint_of_PROJECTAA_Certificate = $Cert_output.Thumbprint # 用New-WSManInstance创建HTTPS监听器 $listenerParams = @{ ResourceURI = "winrm/config/Listener" SelectorSet = @{ Address = "*" Transport = "HTTPS" } ValueSet = @{ Hostname = $FQDN_of_LocalMachine CertificateThumbprint = $Thumbprint_of_PROJECTAA_Certificate } } try { New-WSManInstance @listenerParams Write-Host "WinRM HTTPS listener created successfully" } catch { Write-Host "Failed to create WinRM HTTPS listener: $_" } } } Function ConfigureWINRM { $state_of_WinRM_https = CheckWinRMHTTPSConfiguration if($state_of_WinRM_https -eq $true){ Write-Host "Deleting existing WinRM HTTPS listener" # 用Remove-WSManInstance删除现有监听器 try { Get-WSManInstance -ResourceURI winrm/config/Listener -SelectorSet @{Address="*";Transport="HTTPS"} | Remove-WSManInstance -ErrorAction Stop Write-Host "Existing WinRM HTTPS listener deleted" } catch { Write-Host "Failed to delete existing WinRM HTTPS listener: $_" } ConfigureWinRMwithPROJECTAACertificate_https } else { Write-Host "Configuring WinRM HTTPS listener" ConfigureWinRMwithPROJECTAACertificate_https } } Function Update_grouppolicy{ # 用Start-Process替代Invoke-Expression,更安全可控 $gpProcess = Start-Process -FilePath "gpupdate.exe" -ArgumentList "/force /wait:-1 /target:computer" -NoNewWindow -PassThru -Wait Start-Sleep -Seconds 300 return $gpProcess.ExitCode } $gpExitCode = Update_grouppolicy # 更可靠的判断组策略更新结果 if ($gpExitCode -eq 0) { Write-Host "Computer Policy update has completed successfully" Write-Host "Configuring WinRM with HTTPS..." ConfigureWINRM } else { Write-Host "Group policy did not update successfully. Thus WinRM configuration with HTTPS is skipped." }
额外优化说明
- 替换了
Invoke-Expression调用gpupdate的方式,改用Start-Process,更安全且能通过退出码精准判断组策略更新结果 - 给WSMan cmdlet添加了错误捕获,方便排查配置失败的具体原因
- 提前过滤符合模板的证书,简化后续逻辑判断的复杂度
备注:内容来源于stack exchange,提问作者Vijayanand Arunagiri
相关产品推荐
相关产品推荐

