def _execute_command(self, device, command): """ Create WinRS client and run the command remotely. """ winrs = SingleCommandClient(self._conn_info(device)) result = winrs.run_command(str(command)) result.addCallback(lambda res: self._on_success(device, res, command)) result.addErrback(lambda err: self._on_error(device, err))
class IISCommander(object): def __init__(self, conn_info): self.winrs = SingleCommandClient(conn_info) PS_COMMAND = "powershell -NoLogo -NonInteractive -NoProfile " \ "-OutputFormat TEXT -Command " IIS_COMMAND = ''' $iisversion = get-itemproperty HKLM:\SOFTWARE\Microsoft\InetStp\ | select versionstring; Write-Host $iisversion.versionstring; ''' def get_app_pool_status(self): script = '"& {$Host.UI.RawUI.BufferSize = New-Object Management.Automation.Host.Size(4096, 1024);'\ ' get-counter \'\APP_POOL_WAS(*)\Current Application Pool State\'}' return self.winrs.run_command(self.PS_COMMAND, ps_script=script) def get_iis_version(self): script = '"& {{{}}}"'.format(self.IIS_COMMAND.replace('\n', ' ')) return self.winrs.run_command(self.PS_COMMAND, ps_script=script)
def collect(self, config): dsconf0 = config.datasources[0] conn_info = createConnectionInfo(dsconf0) strategy = queryUtility(IStrategy, dsconf0.params['strategy']) if not strategy: raise WindowsShellException("No strategy chosen for {0}".format( dsconf0.datasource)) counters = [dsconf.params['resource'] for dsconf in config.datasources] if dsconf0.params['strategy'].startswith('powershell MSSQL'): cmd_line_input, conn_info = self.getSQLConnection( dsconf0, conn_info) if dsconf0.params['strategy'] == 'powershell MSSQL Instance': owner_node, server = dsconf.cluster_node_server.split('//') if len(server.split('\\')) < 2: cmd_line_input = 'MSSQLSERVER' else: cmd_line_input = dsconf0.params['instanceid'] if dsconf.params['strategy'] == 'powershell MSSQL' or\ dsconf.params['strategy'] == 'powershell MSSQL Job': conn_info = conn_info._replace(timeout=dsconf0.cycletime - 5) command_line, script = strategy.build_command_line(cmd_line_input) elif dsconf0.params['strategy'] == 'Custom Command': check_datasource(dsconf0) script = dsconf0.params['script'] usePowershell = dsconf0.params['usePowershell'] command_line, script = strategy.build_command_line( script, usePowershell) elif dsconf0.params['strategy'] == 'DCDiag': testparms = [ dsconf.params['script'] for dsconf in config.datasources if dsconf.params['script'] ] command_line = strategy.build_command_line( counters, testparms, dsconf0.windows_user, dsconf0.windows_password) conn_info = conn_info._replace(timeout=180) script = None else: command_line, script = strategy.build_command_line(counters) command = SingleCommandClient(conn_info) self.start = time.mktime(time.localtime()) results = yield command.run_command(command_line, script) defer.returnValue((strategy, config.datasources, results))
def collect(self, config): dsconf0 = config.datasources[0] conn_info = createConnectionInfo(dsconf0) strategy = queryUtility(IStrategy, dsconf0.params['strategy']) if not strategy: raise WindowsShellException( "No strategy chosen for {0}".format(dsconf0.datasource) ) counters = [dsconf.params['resource'] for dsconf in config.datasources] if dsconf0.params['strategy'].startswith('powershell MSSQL'): cmd_line_input, conn_info = self.getSQLConnection(dsconf0, conn_info) if dsconf0.params['strategy'] == 'powershell MSSQL Instance': owner_node, server = dsconf.cluster_node_server.split('//') if len(server.split('\\')) < 2: cmd_line_input = 'MSSQLSERVER' else: cmd_line_input = dsconf0.params['instanceid'] if dsconf.params['strategy'] == 'powershell MSSQL' or\ dsconf.params['strategy'] == 'powershell MSSQL Job': conn_info = conn_info._replace(timeout=dsconf0.cycletime - 5) command_line, script = strategy.build_command_line(cmd_line_input) elif dsconf0.params['strategy'] == 'Custom Command': check_datasource(dsconf0) script = dsconf0.params['script'] usePowershell = dsconf0.params['usePowershell'] command_line, script = strategy.build_command_line(script, usePowershell) elif dsconf0.params['strategy'] == 'DCDiag': testparms = [dsconf.params['script'] for dsconf in config.datasources if dsconf.params['script']] command_line = strategy.build_command_line(counters, testparms, dsconf0.windows_user, dsconf0.windows_password) conn_info = conn_info._replace(timeout=180) script = None else: command_line, script = strategy.build_command_line(counters) command = SingleCommandClient(conn_info) self.start = time.mktime(time.localtime()) results = yield command.run_command(command_line, script) defer.returnValue((strategy, config.datasources, results))
class ClusterCommander(object): def __init__(self, conn_info): self.winrs = SingleCommandClient(conn_info) pscommand = "powershell -NoLogo -NonInteractive -NoProfile " \ "-OutputFormat TEXT -Command " psClusterCommands = [] psClusterCommands.append("$Host.UI.RawUI.BufferSize = New-Object Management.Automation.Host.Size (512, 512);") psClusterCommands.append("import-module failoverclusters;") def run_command(self, command): """Run command for powershell failover clusters""" if isinstance(command, str): command = command.splitlines() command = "\"& {{{}}}\"".format( ''.join(self.psClusterCommands + command) ) return self.winrs.run_command(self.pscommand, ps_script=command)
class ClusterCommander(object): def __init__(self, conn_info): self.winrs = SingleCommandClient(conn_info) pscommand = "powershell -NoLogo -NonInteractive -NoProfile " \ "-OutputFormat TEXT -Command " psClusterCommands = [] psClusterCommands.append( "$Host.UI.RawUI.BufferSize = New-Object Management.Automation.Host.Size (512, 512);" ) psClusterCommands.append("import-module failoverclusters;") def run_command(self, command): """Run command for powershell failover clusters""" if isinstance(command, str): command = command.splitlines() command = "\"& {{{}}}\"".format(''.join(self.psClusterCommands + command)) return self.winrs.run_command(self.pscommand, ps_script=command)
class EventLogQuery(object): def __init__(self, conn_info): self.winrs = SingleCommandClient(conn_info) PS_COMMAND = "powershell -NoLogo -NonInteractive -NoProfile " \ "-OutputFormat TEXT -Command " PS_SCRIPT = ''' $FormatEnumerationLimit = -1; $Host.UI.RawUI.BufferSize = New-Object Management.Automation.Host.Size(4096, 1024); function sstring($s) {{ if ($s -eq $null) {{ return ""; }}; if ($s.GetType() -eq [System.Security.Principal.SecurityIdentifier]) {{ [String]$s = $s.Translate( [System.Security.Principal.NTAccount]); }} elseif ($s.GetType() -ne [String]) {{ [String]$s = $s; }}; $s = $s.replace("`r","").replace("`n"," "); $s = $s.replace('"', '\\"').replace("\\'","'"); $s = $s.replace("`t", " "); return "$($s)".replace('\\','\\\\').trim(); }}; function EventLogToJSON {{ begin {{ $first = $True; '[' }} process {{ if ($first) {{ $separator = ""; $first = $False; }} else {{ $separator = ","; }} $separator + "{{ `"EntryType`": `"$(sstring($_.EntryType))`", `"TimeGenerated`": `"$(sstring($_.TimeGenerated))`", `"Source`": `"$(sstring($_.Source))`", `"InstanceId`": `"$(sstring($_.InstanceId))`", `"Message`": `"$(sstring($_.Message))`", `"UserName`": `"$(sstring($_.UserName))`", `"MachineName`": `"$(sstring($_.MachineName))`", `"EventID`": `"$(sstring($_.EventID))`" }}" }} end {{ ']' }} }}; function EventLogRecordToJSON {{ begin {{ $first = $True; '[' }} process {{ if ($first) {{ $separator = ""; $first = $False; }} else {{ $separator = ","; }} $separator + "{{ `"EntryType`": `"$(sstring($_.LevelDisplayName))`", `"TimeGenerated`": `"$(sstring($_.TimeCreated))`", `"Source`": `"$(sstring($_.ProviderName))`", `"InstanceId`": `"$(sstring($_.Id))`", `"Message`": `"$(if ($_.Message){{$(sstring($_.Message))}}else{{$(sstring($_.FormatDescription()))}})`", `"UserName`": `"$(sstring($_.UserId))`", `"MachineName`": `"$(sstring($_.MachineName))`", `"EventID`": `"$(sstring($_.Id))`" }}" }} end {{ ']' }} }}; function get_new_recent_entries($logname, $selector, $max_age, $eventid) {{ $x=New-Item HKCU:\SOFTWARE\zenoss -ea SilentlyContinue; $x=New-Item HKCU:\SOFTWARE\zenoss\logs -ea SilentlyContinue; $last_read = Get-ItemProperty -Path HKCU:\SOFTWARE\zenoss\logs -Name $eventid -ea SilentlyContinue; [DateTime]$yesterday = (Get-Date).AddHours(-$max_age); [DateTime]$after = $yesterday; if ($last_read) {{ $last_read = [DateTime]$last_read.$eventid; if ($last_read -gt $yesterday) {{ $after = $last_read; }}; }}; $win2003 = [environment]::OSVersion.Version.Major -lt 6; $dotnets = Get-ChildItem 'HKLM:\\software\\microsoft\\net framework setup\\ndp'| % {{$_.name.split('\\')[5]}} | ? {{ $_ -match 'v3.5|v[45].*'}}; if ($win2003 -eq $false -and $dotnets -ne $null) {{ $query = '{filter_xml}'; [Array]$events = Get-WinEvent -FilterXml $query.replace("{{logname}}",$logname).replace("{{time}}", ((Get-Date) - $after).TotalMilliseconds); }} else {{ [Array]$events = Get-EventLog -After $after -LogName $logname; }}; [DateTime]$last_read = get-date; Set-Itemproperty -Path HKCU:\SOFTWARE\zenoss\logs -Name $eventid -Value ([String]$last_read); if ($events -eq $null) {{ return; }}; if($events) {{ [Array]::Reverse($events); }}; if ($win2003 -and $dotnets -eq $null) {{ @($events | ? $selector) | EventLogToJSON }} else {{ @($events | ? $selector) | EventLogRecordToJSON }} }}; get_new_recent_entries -logname "{eventlog}" -selector {selector} -max_age {max_age} -eventid "{eventid}"; ''' def run(self, eventlog, selector, max_age, eventid, isxml): if selector.strip() == '*': selector = '{$True}' else: selector = selector.replace('\n', ' ').replace('"', r'\"') if isxml: filter_xml = selector selector = '{$True}' else: filter_xml = FILTER_XML.replace('"', r'\"') ps_script = ' '.join([x.strip() for x in self.PS_SCRIPT.split('\n')]) script = "\"& {{{}}}\"".format( ps_script.replace('\n', ' ').replace('"', r'\"').format( eventlog=eventlog or 'System', selector=selector or '{$True}', max_age=max_age or '24', eventid=eventid, filter_xml=filter_xml)) log.debug('sending event script: {}'.format(script)) return self.winrs.run_command(self.PS_COMMAND, ps_script=script)
class SQLCommander(object): ''' Custom WinRS client to construct and run PowerShell commands. ''' def __init__(self, conn_info): self.winrs = SingleCommandClient(conn_info) PS_COMMAND = "powershell -NoLogo -NonInteractive -NoProfile " \ "-OutputFormat TEXT -Command " LOCAL_INSTANCES_PS_SCRIPT = ''' <# Get registry key for instances (with 2003 or 32/64 Bit 2008 base key) #> $reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $hostname); $baseKeys = 'SOFTWARE\Microsoft\Microsoft SQL Server', 'SOFTWARE\Wow6432Node\Microsoft\Microsoft SQL Server'; foreach ($regPath in $baseKeys) { $regKey= $reg.OpenSubKey($regPath); If ($regKey -eq $null) {Continue}; <# Get installed instances' names (both cluster and local) #> If ($regKey.GetSubKeyNames() -contains 'Instance Names') { $regKey = $reg.OpenSubKey($regpath+'\Instance Names\SQL'); $instances = @($regkey.GetValueNames()); } ElseIf ($regKey.GetValueNames() -contains 'InstalledInstances') { $instances = $regKey.GetValue('InstalledInstances'); } Else {Continue}; <# Get only local instances' names #> $local_instances = New-Object System.Collections.Arraylist; $instances | % { $instanceValue = $regKey.GetValue($_); $instanceReg = $reg.OpenSubKey($regpath+'\\'+$instanceValue); If ($instanceReg.GetSubKeyNames() -notcontains 'Cluster') { $version = $instanceReg.OpenSubKey('MSSQLServer\CurrentVersion').GetValue('CurrentVersion'); $instance_ver = $_;$instance_ver+=':';$instance_ver+=$version; $local_instances += $_+':'+$version; }; }; break; }; $local_instances | % {write-host \"instances:\"$_}; ''' CLUSTER_INSTANCES_PS_SCRIPT = ''' $domain = (gwmi WIN32_ComputerSystem).Domain; Import-Module FailoverClusters; $cluster_instances = Get-ClusterResource | ? {$_.ResourceType -like 'SQL Server'} | % {$ownernode = $_.OwnerNode; $_ | Get-ClusterParameter -Name VirtualServerName,InstanceName | Group ClusterObject | Select @{Name='SQLInstance';Expression={($_.Group | select -expandproperty Value) -join '\\'}}, @{Name='OwnerNode';Expression={($ownernode, $domain) -join '.'}}}; $cluster_instances | % {write-host \"instances:\"($_).OwnerNode\($_).SQLInstance}; ''' HOSTNAME_PS_SCRIPT = ''' $hostname = hostname; write-host \"hostname:\"$hostname; ''' def get_instances_names(self, is_cluster): """Run script to retrieve DB instances' names and hostname either available in the cluster or installed on the local machine, according to the 'is_cluster' parameter supplied. """ psinstance_script = self.CLUSTER_INSTANCES_PS_SCRIPT if is_cluster \ else self.LOCAL_INSTANCES_PS_SCRIPT return self.run_command(psinstance_script + self.HOSTNAME_PS_SCRIPT) @defer.inlineCallbacks def run_command(self, pscommand): """Run PowerShell command.""" buffer_size = ('$Host.UI.RawUI.BufferSize = New-Object ' 'Management.Automation.Host.Size (4096, 512);') script = "\"{0} & {{{1}}}\"".format(buffer_size, pscommand.replace('\n', ' ')) results = yield self.winrs.run_command(self.PS_COMMAND, ps_script=script) defer.returnValue(results)
def collect(self, config): conn_info = createConnectionInfo(config.datasources[0]) command = SingleCommandClient(conn_info) pscommand, script = self.build_command_line() results = yield command.run_command(pscommand, script) defer.returnValue(results)
class SQLCommander(object): ''' Custom WinRS client to construct and run PowerShell commands. ''' def __init__(self, conn_info, log): self.winrs = SingleCommandClient(conn_info) self.log = log PS_COMMAND = "powershell -NoLogo -NonInteractive -NoProfile " \ "-OutputFormat TEXT -Command " LOCAL_INSTANCES_PS_SCRIPT = ''' <# Get registry key for instances (with 2003 or 32/64 Bit 2008 base key) #> $reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $hostname); $baseKeys = 'SOFTWARE\Microsoft\Microsoft SQL Server', 'SOFTWARE\Wow6432Node\Microsoft\Microsoft SQL Server'; foreach ($regPath in $baseKeys) { $regKey= $reg.OpenSubKey($regPath); If ($regKey -eq $null) {Continue}; <# Get installed instances' names (both cluster and local) #> If ($regKey.GetSubKeyNames() -contains 'Instance Names') { $regKey = $reg.OpenSubKey($regpath+'\Instance Names\SQL'); $instances = @($regkey.GetValueNames()); } ElseIf ($regKey.GetValueNames() -contains 'InstalledInstances') { $instances = $regKey.GetValue('InstalledInstances'); } Else {Continue}; <# Get only local instances' names #> $local_instances = New-Object System.Collections.Arraylist; $instances | % { $instanceValue = $regKey.GetValue($_); $instanceReg = $reg.OpenSubKey($regpath+'\\'+$instanceValue); If ($instanceReg.GetSubKeyNames() -notcontains 'Cluster') { $version = $instanceReg.OpenSubKey('MSSQLServer\CurrentVersion').GetValue('CurrentVersion'); $instance_ver = $_;$instance_ver+=':';$instance_ver+=$version; $local_instances += $_+':'+$version; }; }; break; }; $local_instances | % {write-host \"instances:\"$_}; ''' CLUSTER_INSTANCES_PS_SCRIPT = ''' $domain = (gwmi WIN32_ComputerSystem).Domain; Import-Module FailoverClusters; $cluster_instances = Get-ClusterResource | ? {$_.ResourceType -like 'SQL Server'} | % {$ownernode = $_.OwnerNode; $_ | Get-ClusterParameter -Name VirtualServerName,InstanceName | Group ClusterObject | Select @{Name='SQLInstance';Expression={($_.Group | select -expandproperty Value) -join '\\'}}, @{Name='OwnerNode';Expression={($ownernode, $domain) -join '.'}}, @{Name='IPv4';Expression={[regex]::match((ping -4 -a -n 1 $ownernode| select-string 'Pinging').ToString(), '(\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\b)').value}}}; $cluster_instances | % {write-host \"instances:\"($_).OwnerNode\($_).IPv4\($_).SQLInstance}; ''' HOSTNAME_PS_SCRIPT = ''' $hostname = hostname; write-host \"hostname:\"$hostname; ''' def get_instances_names(self, is_cluster): """Run script to retrieve DB instances' names and hostname either available in the cluster or installed on the local machine, according to the 'is_cluster' parameter supplied. """ psinstance_script = self.CLUSTER_INSTANCES_PS_SCRIPT if is_cluster \ else self.LOCAL_INSTANCES_PS_SCRIPT return self.run_command( psinstance_script + self.HOSTNAME_PS_SCRIPT ) @defer.inlineCallbacks def run_command(self, pscommand): """Run PowerShell command.""" buffer_size = ('$Host.UI.RawUI.BufferSize = New-Object ' 'Management.Automation.Host.Size (4096, 512);') script = "\"& {{{0} {1}}}\"".format( buffer_size, pscommand.replace('\n', ' ')) self.log.debug(script) results = yield self.winrs.run_command(self.PS_COMMAND, ps_script=script) defer.returnValue(results)
def collect(self, device, log): """ Collect results of the class' queries and commands. This method can be overridden if more complex collection is required. """ try: conn_info = self.conn_info(device) except UnauthorizedError as e: msg = "Error on {}: {}".format(device.id, e.message) self._send_event(msg, device.id, ZenEventClasses.Error, eventClass='/Status/Winrm', summary=msg) raise e client = self.client(conn_info) results = {} queries = self.get_queries() if queries: query_map = { enuminfo: key for key, enuminfo in self.enuminfo_tuples()} # Silence winrm logging. We want to control the message. winrm_log = logging.getLogger('winrm') winrm_log.setLevel(logging.FATAL) try: query_results = yield client.do_collect( query_map.iterkeys()) except Exception as e: self.log_error(log, device, e) else: for info, data in query_results.iteritems(): results[query_map[info]] = data # Get associators. associators = self.get_associators() if associators: assoc_client = AssociatorClient(conn_info) for assoc_key, associator in associators.iteritems(): try: if not associator.get('kwargs'): assoc_result = yield assoc_client.associate( associator['seed_class'], associator['associations']) else: assoc_result = yield assoc_client.associate( associator['seed_class'], associator['associations'], **associator['kwargs']) except Exception as e: if 'No results for seed class' in e.message: message = 'No results returned for {}. Check WinRM server'\ ' configuration and z properties.'.format(self.name()) e = Exception(message) self.log_error(log, device, e) else: results[assoc_key] = assoc_result # Get a copy of the class' commands. commands = dict(self.get_commands()) # Add PowerShell commands to commands. powershell_commands = self.get_powershell_commands() if powershell_commands: for psc_key, psc in powershell_commands.iteritems(): commands[psc_key] = '"& {{{}}}"'.format(psc) if commands: for command_key, command in commands.iteritems(): winrs_client = SingleCommandClient(conn_info) try: if command.startswith('"&'): results[command_key] = yield winrs_client.run_command(POWERSHELL_PREFIX, ps_script=command) else: results[command_key] = yield winrs_client.run_command(command) except Exception as e: self.log_error(log, device, e) msg = 'Collection completed for %s' for eventClass in ('/Status/Winrm', '/Status/Kerberos'): self._send_event(msg % device.id, device.id, ZenEventClasses.Clear, eventClass=eventClass) defer.returnValue(results)
class EventLogQuery(object): def __init__(self, conn_info): self.winrs = SingleCommandClient(conn_info) PS_COMMAND = "powershell -NoLogo -NonInteractive -NoProfile " \ "-OutputFormat TEXT -Command " PS_SCRIPT = ''' $FormatEnumerationLimit = -1; $Host.UI.RawUI.BufferSize = New-Object Management.Automation.Host.Size(4096, 1024); function sstring($s) {{ if ($s -eq $null) {{ return ""; }}; if ($s.GetType() -eq [System.Security.Principal.SecurityIdentifier]) {{ [String]$s = $s.Translate( [System.Security.Principal.NTAccount]); }} elseif ($s.GetType() -ne [String]) {{ [String]$s = $s; }}; $s = $s.replace("`r","").replace("`n"," "); $s = $s.replace('"', '\\"').replace("\\'","'"); $s = $s.replace("`t", " "); return "$($s)".replace('\\','\\\\').trim(); }}; function EventLogToJSON {{ begin {{ $first = $True; '[' }} process {{ if ($first) {{ $separator = ""; $first = $False; }} else {{ $separator = ","; }} $separator + "{{ `"EntryType`": `"$(sstring($_.EntryType))`", `"TimeGenerated`": `"$(sstring($_.TimeGenerated))`", `"Source`": `"$(sstring($_.Source))`", `"InstanceId`": `"$(sstring($_.InstanceId))`", `"Message`": `"$(sstring($_.Message))`", `"UserName`": `"$(sstring($_.UserName))`", `"MachineName`": `"$(sstring($_.MachineName))`", `"EventID`": `"$(sstring($_.EventID))`" }}" }} end {{ ']' }} }}; function EventLogRecordToJSON {{ begin {{ $first = $True; '[' }} process {{ if ($first) {{ $separator = ""; $first = $False; }} else {{ $separator = ","; }} $separator + "{{ `"EntryType`": `"$(sstring($_.LevelDisplayName))`", `"TimeGenerated`": `"$(sstring($_.TimeCreated))`", `"Source`": `"$(sstring($_.ProviderName))`", `"InstanceId`": `"$(sstring($_.Id))`", `"Message`": `"$(if ($_.Message){{$(sstring($_.Message))}}else{{$(sstring($_.FormatDescription()))}})`", `"UserName`": `"$(sstring($_.UserId))`", `"MachineName`": `"$(sstring($_.MachineName))`", `"EventID`": `"$(sstring($_.Id))`" }}" }} end {{ ']' }} }}; function get_new_recent_entries($logname, $selector, $max_age, $eventid) {{ $x=New-Item HKCU:\SOFTWARE\zenoss -ea SilentlyContinue; $x=New-Item HKCU:\SOFTWARE\zenoss\logs -ea SilentlyContinue; $last_read = Get-ItemProperty -Path HKCU:\SOFTWARE\zenoss\logs -Name $eventid -ea SilentlyContinue; [DateTime]$yesterday = (Get-Date).AddHours(-$max_age); [DateTime]$after = $yesterday; if ($last_read) {{ $last_read = [DateTime]$last_read.$eventid; if ($last_read -gt $yesterday) {{ $after = $last_read; }}; }}; $win2003 = [environment]::OSVersion.Version.Major -lt 6; $dotnets = ($PSVersionTable.CLRVersion.Major + ($PSVersionTable.CLRVersion.Minor/10)) -ge 3.5; if ($win2003 -eq $false -and $dotnets -eq $true) {{ $query = '{filter_xml}'; [Array]$events = Get-WinEvent -FilterXml $query.replace("{{logname}}",$logname).replace("{{time}}", ((Get-Date) - $after).TotalMilliseconds); }} else {{ [Array]$events = Get-EventLog -After $after -LogName $logname; }}; [DateTime]$last_read = get-date; Set-Itemproperty -Path HKCU:\SOFTWARE\zenoss\logs -Name $eventid -Value ([String]$last_read); if ($events -eq $null) {{ return; }}; if($events) {{ [Array]::Reverse($events); }}; if ($win2003 -and $dotnets -eq $null) {{ @($events | ? $selector) | EventLogToJSON }} else {{ @($events | ? $selector) | EventLogRecordToJSON }} }}; get_new_recent_entries -logname "{eventlog}" -selector {selector} -max_age {max_age} -eventid "{eventid}"; ''' def run(self, eventlog, selector, max_age, eventid, isxml): if selector.strip() == '*': selector = '{$True}' else: selector = selector.replace('\n', ' ').replace('"', r'\"') if isxml: filter_xml = selector selector = '{$True}' else: filter_xml = FILTER_XML.replace('"', r'\"') ps_script = ' '.join([x.strip() for x in self.PS_SCRIPT.split('\n')]) script = "\"& {{{}}}\"".format( ps_script.replace('\n', ' ').replace('"', r'\"').format( eventlog=eventlog or 'System', selector=selector or '{$True}', max_age=max_age or '24', eventid=eventid, filter_xml=filter_xml ) ) log.debug('sending event script: {}'.format(script)) return self.winrs.run_command(self.PS_COMMAND, ps_script=script)
def collect(self, device, log): """ Collect results of the class' queries and commands. This method can be overridden if more complex collection is required. """ try: conn_info = self.conn_info(device) except UnauthorizedError as e: msg = "Error on {}: {}".format(device.id, e.message) self._send_event(msg, device.id, ZenEventClasses.Error, eventClass='/Status/Winrm', summary=msg) raise e client = self.client(conn_info) results = {} queries = self.get_queries() if queries: query_map = { enuminfo: key for key, enuminfo in self.enuminfo_tuples() } # Silence winrm logging. We want to control the message. winrm_log = logging.getLogger('winrm') winrm_log.setLevel(logging.FATAL) try: query_results = yield client.do_collect(query_map.iterkeys()) except Exception as e: self.log_error(log, device, e) else: for info, data in query_results.iteritems(): results[query_map[info]] = data # Get associators. associators = self.get_associators() if associators: assoc_client = AssociatorClient(conn_info) for assoc_key, associator in associators.iteritems(): try: if not associator.get('kwargs'): assoc_result = yield assoc_client.associate( associator['seed_class'], associator['associations']) else: assoc_result = yield assoc_client.associate( associator['seed_class'], associator['associations'], **associator['kwargs']) except Exception as e: if 'No results for seed class' in e.message: message = 'No results returned for {}. Check WinRM server'\ ' configuration and z properties.'.format(self.name()) e = Exception(message) self.log_error(log, device, e) else: results[assoc_key] = assoc_result # Get a copy of the class' commands. commands = dict(self.get_commands()) # Add PowerShell commands to commands. powershell_commands = self.get_powershell_commands() if powershell_commands: for psc_key, psc in powershell_commands.iteritems(): commands[psc_key] = '"& {{{}}}"'.format(psc) if commands: for command_key, command in commands.iteritems(): winrs_client = SingleCommandClient(conn_info) try: if command.startswith('"&'): results[command_key] = yield winrs_client.run_command( POWERSHELL_PREFIX, ps_script=command) else: results[command_key] = yield winrs_client.run_command( command) except Exception as e: self.log_error(log, device, e) msg = 'Collection completed for %s' for eventClass in ('/Status/Winrm', '/Status/Kerberos'): self._send_event(msg % device.id, device.id, ZenEventClasses.Clear, eventClass=eventClass) defer.returnValue(results)