我编写了第一个Powershell脚本,以获取有关在3台WSUS服务器上分派的大约300台服务器的统计信息。有一个上游服务器和两个下游服务器(一个自治服务器和一个副本服务器)。
在执行之前,借助于ansible剧本(使用winrm连接)将powershell脚本发送到上游服务器。
该脚本仅解析两个已配置的主机(上游和自治下游),然后调用Get-WsusServer和后续例程以获取我需要的数据。
当powershell脚本直接在上游主机上运行时,一切都很好,带有自治服务器的Get-WsusServer可以工作。
当powershell脚本由ansible剧本运行时,当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时执行失败的剧本之间的行为差异。
附加信息: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....
这本有趣的剧本非常基础,在复制脚本后仅播放win_shell模块。如果我仅查询上游,则可玩游戏100%确定。
---
- 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>
确定]
https://docs.ansible.com/ansible/latest/user_guide/windows_winrm.html#authentication-optionshttps://docs.ansible.com/ansible/2.5/user_guide/become.html#become-and-windows
ntlm方法无法让您正确假设您要用来运行win_shell命令或指令的帐户。
我不得不将ntlm换成kerberos,并使用runas方法来成为功能,并指定用于Winrm连接的完全相同的帐户。
正在运行。