【发布时间】:2019-12-31 13:54:13
【问题描述】:
我正在编写我的第一个 powershell 脚本来获取有关在 3 个 WSUS 服务器上调度的大约 300 个服务器的统计信息。有一个上游和两个下游服务器(一个自治和一个副本)。
在 ansible playbook 的帮助下(使用 winrm 连接),powershell 脚本在执行前被发送到上游服务器。
该脚本仅解析两个已配置的主机(上游和自主下游),然后调用 Get-WsusServer 和后续例程来获取我需要的数据。
直接在上游主机上运行powershell脚本时,一切正常,带有自治服务器的Get-WsusServer工作。
当由 ansible playbook 运行 powershell 脚本时,当 Get-WsusServer 例程调用自治下游服务器时,它会失败并出现以下错误:
"stderr_lines": [
"Get-WsusServer : The request failed with HTTP status 401: Unauthorized.",
"At D:\\Reports\\wsusreport.ps1:74 char:11",
"+ $wsus = Get-WsusServer -Name $wsusserver -PortNumber 8530",
"+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
" + CategoryInfo : InvalidData: (Microsoft.Updat...usServerCommand:GetWsusServerCommand) [Get-WsusServer], ",
" WebException",
" + FullyQualifiedErrorId : ServerIsInvalid,Microsoft.UpdateServices.Commands.GetWsusServerCommand",
" ",
"You cannot call a method on a null-valued expression.",
"At D:\\Reports\\wsusreport.ps1:80 char:3",
"+ $classifications=$wsus.GetUpdateClassifications() |",
"+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~",
" + CategoryInfo : InvalidOperation: (:) [], RuntimeException",
" + FullyQualifiedErrorId : InvokeMethodOnNull",
" ",
"Exception calling \"AddRange\" with \"1\" argument(s): \"Value cannot be null.",
"Parameter name: value\"",
我尝试使用具有本地管理员权限的域帐户以及本地管理员帐户。但我无法确定问题到底是什么。
而且我无法解释成功的本地执行与在针对自主下游服务器调用 Get-WsusServer 时失败的 playbook 执行之间的行为差异。
附加信息: powershell 脚本循环如下所示:
$Target_WSUS_Server_host = "upstream", "downstream"
foreach ($domain in $Target_WSUS_Server_Host) {
Write-Host "Working on : $domain"
[void][reflection.assembly]::LoadWithPartialName('Microsoft.UpdateServices.Administration')
$wsus = Get-WsusServer -Name $domain -PortNumber 8530
# Scope initialization
$computerscope = New-Object Microsoft.UpdateServices.Administration.ComputerTargetScope
$computerscope.IncludeDownstreamComputerTargets = 'true'
etc....
playbook 的 ansible 部分非常基础,只是在复制脚本后播放 win_shell 模块。如果我只查询上游,ansible play 100% OK。
---
- name: wsus report generation
hosts: upstream
vars:
local_dir: "./data/"
local_script: "wsusreport.ps1"
remote_script_log: "wsusreport.log"
remote_dir: 'D:\Reports\'
script_log: "wsusreport.log"
yearmonth: "{{ lookup('pipe', 'date +%Y-%m') }}"
tasks:
- name: copy ps1 script to wsus server
tags:
- sendscript
win_copy:
src: "{{ local_dir }}/{{ local_script }}"
dest: "{{ remote_dir }}"
- name: execute script
tags:
- exescript
win_shell: "{{ remote_dir }}\\{{ local_script }} downstream {{ yearmonth }} > {{ remote_dir }}\\{{ remote_script_log }}"
powershell 脚本有两个参数, 第一个是一个开关,用于确定我是否只想要上游数据、下游数据或两者兼而有之。 第二个是我要检索的时间范围,默认为当前补丁星期二活动。
其他信息
在安全事件日志中,当脚本被 ansible 删除并调用时会发生什么: - 有一个带有这些详细信息的登录/注销事件:
- <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
- <System>
<Provider Name="Microsoft-Windows-Security-Auditing" Guid="{54849625-5478-4994-A5BA-3E3B0328C30D}" />
<EventID>4624</EventID>
<Version>2</Version>
<Level>0</Level>
<Task>12544</Task>
<Opcode>0</Opcode>
<Keywords>0x8020000000000000</Keywords>
<TimeCreated SystemTime="2020-01-03T15:44:11.016233500Z" />
<EventRecordID>3662170</EventRecordID>
<Correlation ActivityID="{1715CB99-B4FA-0001-A1CB-1517FAB4D501}" />
<Execution ProcessID="792" ThreadID="4316" />
<Channel>Security</Channel>
<Computer>*FQDN of the downstream server*</Computer>
<Security />
</System>
- <EventData>
<Data Name="SubjectUserSid">S-1-0-0</Data>
<Data Name="SubjectUserName">-</Data>
<Data Name="SubjectDomainName">-</Data>
<Data Name="SubjectLogonId">0x0</Data>
<Data Name="TargetUserSid">S-1-5-7</Data>
<Data Name="TargetUserName">ANONYMOUS LOGON</Data> <===== /!\
<Data Name="TargetDomainName">NT AUTHORITY</Data>
<Data Name="TargetLogonId">0x13316e110</Data>
<Data Name="LogonType">3</Data>
<Data Name="LogonProcessName">NtLmSsp</Data>
<Data Name="AuthenticationPackageName">NTLM</Data>
<Data Name="WorkstationName">*Hostname of the upstream server*</Data>
<Data Name="LogonGuid">{00000000-0000-0000-0000-000000000000}</Data>
<Data Name="TransmittedServices">-</Data>
<Data Name="LmPackageName">NTLM V1</Data>
<Data Name="KeyLength">128</Data>
<Data Name="ProcessId">0x0</Data>
<Data Name="ProcessName">-</Data>
<Data Name="IpAddress">*IP Adress of the upstream server*</Data>
<Data Name="IpPort">55186</Data>
<Data Name="ImpersonationLevel">%%1833</Data>
<Data Name="RestrictedAdminMode">-</Data>
<Data Name="TargetOutboundUserName">-</Data>
<Data Name="TargetOutboundDomainName">-</Data>
<Data Name="VirtualAccount">%%1843</Data>
<Data Name="TargetLinkedLogonId">0x0</Data>
<Data Name="ElevatedToken">%%1843</Data>
</EventData>
</Event>
直接在上游服务器上调用脚本时,登录过程要冗长得多,并且使用两个服务器之间相同的本地帐户。
- <Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
- <System>
<Provider Name="Microsoft-Windows-Security-Auditing" Guid="{54849625-5478-4994-A5BA-3E3B0328C30D}" />
<EventID>4624</EventID>
<Version>2</Version>
<Level>0</Level>
<Task>12544</Task>
<Opcode>0</Opcode>
<Keywords>0x8020000000000000</Keywords>
<TimeCreated SystemTime="2020-01-03T15:44:46.197671000Z" />
<EventRecordID>3662174</EventRecordID>
<Correlation ActivityID="{1715CB99-B4FA-0001-A1CB-1517FAB4D501}" />
<Execution ProcessID="792" ThreadID="5672" />
<Channel>Security</Channel>
<Computer>DOWNSTREAM_SERVER_FQDN</Computer>
<Security />
</System>
- <EventData>
<Data Name="SubjectUserSid">S-1-0-0</Data>
<Data Name="SubjectUserName">-</Data>
<Data Name="SubjectDomainName">-</Data>
<Data Name="SubjectLogonId">0x0</Data>
<Data Name="TargetUserSid">S-1-5-21-910770422-2570656215-934337312-1006</Data>
<Data Name="TargetUserName">ACCOUNT_USED_ON_BOTH_SERVERS</Data> <====== OK !
<Data Name="TargetDomainName">DOWNSTREAM_SERVER_HOSTNAME</Data>
<Data Name="TargetLogonId">0x13319dcbb</Data>
<Data Name="LogonType">3</Data>
<Data Name="LogonProcessName">NtLmSsp</Data>
<Data Name="AuthenticationPackageName">NTLM</Data>
<Data Name="WorkstationName">UPSTREAM_SERVER_HOSTNAME</Data>
<Data Name="LogonGuid">{00000000-0000-0000-0000-000000000000}</Data>
<Data Name="TransmittedServices">-</Data>
<Data Name="LmPackageName">NTLM V2</Data>
<Data Name="KeyLength">128</Data>
<Data Name="ProcessId">0x0</Data>
<Data Name="ProcessName">-</Data>
<Data Name="IpAddress">UPSTREAM_SERVER_IP_ADDRESS</Data>
<Data Name="IpPort">55198</Data>
<Data Name="ImpersonationLevel">%%1833</Data>
<Data Name="RestrictedAdminMode">-</Data>
<Data Name="TargetOutboundUserName">-</Data>
<Data Name="TargetOutboundDomainName">-</Data>
<Data Name="VirtualAccount">%%1843</Data>
<Data Name="TargetLinkedLogonId">0x0</Data>
<Data Name="ElevatedToken">%%1842</Data>
</EventData>
</Event>
【问题讨论】:
-
您没有显示复制和运行脚本的 ansible 任务。问题似乎出在某个地方...您是否传递了任何参数?请使用您正在使用的剧本(或至少相关部分)更新您的问题。
-
添加了几行,当我仅拉取上游数据时,剧本运行良好,但是当我要求 powershell 脚本拉取下游数据时,它失败并出现提到的错误。从上游服务器上打开的会话执行时,完全相同的脚本是可以的。
-
您是否尝试在命令中引用日期? `win_shell: "{{ remote_dir }}\\{{ local_script }} 下游 \"{{ yearmonth }}\" > {{ remote_dir }}\\{{ remote_script_log }}"...只是一个想法,否则我'让其他人调查一下,因为我没有其他想法。
-
谢谢,但是脚本在执行过程中失败了,而且看起来和参数无关,其实我只是在没有yearmonth参数的情况下运行,脚本知道如何处理它。当脚本自己尝试使用远程下游服务器获取 WsusServer 时,该错误确实会弹出。虽然在本地使用相同的脚本和相同的参数是可以的,但是登录到上游服务器时。
标签: windows powershell ansible winrm windows-update