From cc7c21c73df8a94625e46346de99ca7df27b8e3f Mon Sep 17 00:00:00 2001 From: Matt Graeber Date: Mon, 24 Oct 2016 06:39:11 -0700 Subject: [PATCH 01/15] Removing -NoProgresBar parameter from functions This is redundant considering a user can just set $ProgressPreference. --- CimSweep/Core/CoreFunctions.ps1 | 81 +++------------- CimSweep/Defense/Autoruns.ps1 | 89 ++++++------------ CimSweep/Defense/SuspiciousFiles.ps1 | 107 ++++++--------------- CimSweep/Defense/SuspiciousURLs.ps1 | 15 +-- CimSweep/Offense/ACLAudits.ps1 | 21 +---- CimSweep/Tests/Core.CimSweep.Tests.ps1 | 124 +++++++++++++------------ README.md | 2 +- 7 files changed, 139 insertions(+), 300 deletions(-) diff --git a/CimSweep/Core/CoreFunctions.ps1 b/CimSweep/Core/CoreFunctions.ps1 index c2807b4..ee39747 100644 --- a/CimSweep/Core/CoreFunctions.ps1 +++ b/CimSweep/Core/CoreFunctions.ps1 @@ -661,10 +661,6 @@ License: BSD 3-Clause Get-CSEventLog lists the available event logs from which event entries can be retrieved via WMI. -.PARAMETER NoProgressBar - -Do not display a progress bar. This parameter is designed to be used with wrapper functions. - .PARAMETER CimSession Specifies the CIM session to use for this cmdlet. Enter a variable that contains the CIM session or a command that creates or gets the CIM session, such as the New-CimSession or Get-CimSession cmdlets. For more information, see about_CimSessions. @@ -703,9 +699,6 @@ Outputs objects representing the available event logs which can be piped to Get- [CmdletBinding()] [OutputType('CimSweep.EventLog')] param( - [Switch] - $NoProgressBar, - [Alias('Session')] [ValidateNotNullOrEmpty()] [Microsoft.Management.Infrastructure.CimSession[]] @@ -736,11 +729,9 @@ Outputs objects representing the available event logs which can be piped to Get- $ComputerName = $Session.ComputerName if (-not $Session.ComputerName) { $ComputerName = 'localhost' } - if (-not $PSBoundParameters['NoProgressBar']) { - # Display a progress activity for each CIM session - Write-Progress -Id 1 -Activity 'CimSweep - Event log sweep' -Status "($($CurrentCIMSession+1)/$($CIMSessionCount)) Current computer: $ComputerName" -PercentComplete (($CurrentCIMSession / $CIMSessionCount) * 100) - $CurrentCIMSession++ - } + # Display a progress activity for each CIM session + Write-Progress -Id 1 -Activity 'CimSweep - Event log sweep' -Status "($($CurrentCIMSession+1)/$($CIMSessionCount)) Current computer: $ComputerName" -PercentComplete (($CurrentCIMSession / $CIMSessionCount) * 100) + $CurrentCIMSession++ $CommonArgs = @{} @@ -840,10 +831,6 @@ Specifies the desired properties to retrieve from Win32_Process instances. The f Specifies the CIM session to use for this cmdlet. Enter a variable that contains the CIM session or a command that creates or gets the CIM session, such as the New-CimSession or Get-CimSession cmdlets. For more information, see about_CimSessions. -.PARAMETER NoProgressBar - -Do not display a progress bar. This parameter is designed to be used with wrapper functions. - .PARAMETER OperationTimeoutSec Specifies the amount of time that the cmdlet waits for a response from the computer. @@ -963,11 +950,6 @@ Outputs Win32_NtLogEvent instances. 'User')] $Property = @('LogFile', 'CategoryString', 'EventCode', 'EventIdentifier', 'Message', 'SourceName', 'TimeGenerated', 'Type'), - [Parameter(ParameterSetName='DefaultOutput')] - [Parameter(ParameterSetName='RestrictOutput')] - [Switch] - $NoProgressBar, - [Parameter(ValueFromPipelineByPropertyName = $True, ParameterSetName='DefaultOutput')] [Parameter(ValueFromPipelineByPropertyName = $True, ParameterSetName='RestrictOutput')] [Alias('Session')] @@ -1003,11 +985,9 @@ Outputs Win32_NtLogEvent instances. $ComputerName = $Session.ComputerName if (-not $Session.ComputerName) { $ComputerName = 'localhost' } - if (-not $PSBoundParameters['NoProgressBar']) { - # Display a progress activity for each CIM session - Write-Progress -Id 1 -Activity 'CimSweep - Event log entry sweep' -Status "($($CurrentCIMSession+1)/$($CIMSessionCount)) Current computer: $ComputerName" -PercentComplete (($CurrentCIMSession / $CIMSessionCount) * 100) - $CurrentCIMSession++ - } + # Display a progress activity for each CIM session + Write-Progress -Id 1 -Activity 'CimSweep - Event log entry sweep' -Status "($($CurrentCIMSession+1)/$($CIMSessionCount)) Current computer: $ComputerName" -PercentComplete (($CurrentCIMSession / $CIMSessionCount) * 100) + $CurrentCIMSession++ $CommonArgs = @{} @@ -1687,10 +1667,6 @@ Specifies that the ACL for the service should be returned. -IncludeAcl will appe Specifies that the ACL file hosting the service be returned. -IncludeFileInfo will append a FileInfo property to each returned object. The FileInfo property is a CIM_DataFile instance. -.PARAMETER NoProgressBar - -Do not display a progress bar. This parameter is designed to be used with wrapper functions. - .PARAMETER CimSession Specifies the CIM session to use for this cmdlet. Enter a variable that contains the CIM session or a command that creates or gets the CIM session, such as the New-CimSession or Get-CimSession cmdlets. For more information, see about_CimSessions. @@ -1820,11 +1796,6 @@ Outputs Win32_Service or Win32_SystemDriver instances both of which derive from [Switch] $IncludeFileInfo, - [Parameter(ParameterSetName='DefaultOutput')] - [Parameter(ParameterSetName='RestrictOutput')] - [Switch] - $NoProgressBar, - [Parameter(ParameterSetName='DefaultOutput')] [Parameter(ParameterSetName='RestrictOutput')] [Alias('Session')] @@ -1964,11 +1935,9 @@ Outputs Win32_Service or Win32_SystemDriver instances both of which derive from $ComputerName = $Session.ComputerName if (-not $Session.ComputerName) { $ComputerName = 'localhost' } - if (-not $PSBoundParameters['NoProgressBar']) { - # Display a progress activity for each CIM session - Write-Progress -Id 1 -Activity 'CimSweep - Service sweep' -Status "($($CurrentCIMSession+1)/$($CIMSessionCount)) Current computer: $ComputerName" -PercentComplete (($CurrentCIMSession / $CIMSessionCount) * 100) - $CurrentCIMSession++ - } + # Display a progress activity for each CIM session + Write-Progress -Id 1 -Activity 'CimSweep - Service sweep' -Status "($($CurrentCIMSession+1)/$($CIMSessionCount)) Current computer: $ComputerName" -PercentComplete (($CurrentCIMSession / $CIMSessionCount) * 100) + $CurrentCIMSession++ $CommonArgs = @{} @@ -2138,10 +2107,6 @@ Specifies that an explicit list of Win32_Process properties should be returned. Specifies the desired properties to retrieve from Win32_Process instances. The following properties are returned when limited output is desired: ProcessId, ParentProcessId, Name, ExecutablePath, CommandLine -.PARAMETER NoProgressBar - -Do not display a progress bar. This parameter is designed to be used with wrapper functions. - .PARAMETER CimSession Specifies the CIM session to use for this cmdlet. Enter a variable that contains the CIM session or a command that creates or gets the CIM session, such as the New-CimSession or Get-CimSession cmdlets. For more information, see about_CimSessions. @@ -2269,11 +2234,6 @@ Outputs Win32_Process instances. 'WriteTransferCount')] $Property = @('ProcessId', 'ParentProcessId', 'Name', 'ExecutablePath', 'CommandLine'), - [Parameter(ParameterSetName='DefaultOutput')] - [Parameter(ParameterSetName='RestrictOutput')] - [Switch] - $NoProgressBar, - [Parameter(ParameterSetName='DefaultOutput')] [Parameter(ParameterSetName='RestrictOutput')] [Alias('Session')] @@ -2309,11 +2269,9 @@ Outputs Win32_Process instances. $ComputerName = $Session.ComputerName if (-not $Session.ComputerName) { $ComputerName = 'localhost' } - if (-not $PSBoundParameters['NoProgressBar']) { - # Display a progress activity for each CIM session - Write-Progress -Id 1 -Activity 'CimSweep - Process sweep' -Status "($($CurrentCIMSession+1)/$($CIMSessionCount)) Current computer: $ComputerName" -PercentComplete (($CurrentCIMSession / $CIMSessionCount) * 100) - $CurrentCIMSession++ - } + # Display a progress activity for each CIM session + Write-Progress -Id 1 -Activity 'CimSweep - Process sweep' -Status "($($CurrentCIMSession+1)/$($CIMSessionCount)) Current computer: $ComputerName" -PercentComplete (($CurrentCIMSession / $CIMSessionCount) * 100) + $CurrentCIMSession++ $CommonArgs = @{} @@ -2364,10 +2322,6 @@ Specifies that only system-scope environment variables should be returned. Specifies that only user-scope environment variables should be returned. -.PARAMETER NoProgressBar - -Do not display a progress bar. This parameter is designed to be used with wrapper functions. - .PARAMETER CimSession Specifies the CIM session to use for this cmdlet. Enter a variable that contains the CIM session or a command that creates or gets the CIM session, such as the New-CimSession or Get-CimSession cmdlets. For more information, see about_CimSessions. @@ -2432,9 +2386,6 @@ Outputs objects consisting of the name, value, and scope (user vs. system) of an [Switch] $UserVariable, - [Switch] - $NoProgressBar, - [Parameter(ParameterSetName = 'Default')] [Parameter(ParameterSetName = 'System')] [Parameter(ParameterSetName = 'User')] @@ -2473,11 +2424,9 @@ Outputs objects consisting of the name, value, and scope (user vs. system) of an $ComputerName = $Session.ComputerName if (-not $Session.ComputerName) { $ComputerName = 'localhost' } - if (-not $PSBoundParameters['NoProgressBar']) { - # Display a progress activity for each CIM session - Write-Progress -Id 1 -Activity 'CimSweep - environment variable sweep' -Status "($($CurrentCIMSession+1)/$($CIMSessionCount)) Current computer: $ComputerName" -PercentComplete (($CurrentCIMSession / $CIMSessionCount) * 100) - $CurrentCIMSession++ - } + # Display a progress activity for each CIM session + Write-Progress -Id 1 -Activity 'CimSweep - environment variable sweep' -Status "($($CurrentCIMSession+1)/$($CIMSessionCount)) Current computer: $ComputerName" -PercentComplete (($CurrentCIMSession / $CIMSessionCount) * 100) + $CurrentCIMSession++ $CommonArgs = @{} diff --git a/CimSweep/Defense/Autoruns.ps1 b/CimSweep/Defense/Autoruns.ps1 index 3bb50fa..c5a1a35 100644 --- a/CimSweep/Defense/Autoruns.ps1 +++ b/CimSweep/Defense/Autoruns.ps1 @@ -51,10 +51,6 @@ Retrieve network provider artifacts Retrieve boot execute artifacts -.PARAMETER NoProgressBar - -Do not display a progress bar. This parameter is designed to be used with wrapper functions. - .PARAMETER CimSession Specifies the CIM session to use for this cmdlet. Enter a variable that contains the CIM session or a command that creates or gets the CIM session, such as the New-CimSession or Get-CimSession cmdlets. For more information, see about_CimSessions. @@ -125,9 +121,6 @@ Outputs objects representing autoruns entries similar to the output of Sysintern [Switch] $BootExecute, - [Switch] - $NoProgressBar, - [Alias('Session')] [ValidateNotNullOrEmpty()] [Microsoft.Management.Infrastructure.CimSession[]] @@ -154,7 +147,6 @@ Outputs objects representing autoruns entries similar to the output of Sysintern $ParamCopy = $PSBoundParameters $null = $ParamCopy.Remove('CimSession') - $null = $ParamCopy.Remove('NoProgressBar') $null = $ParamCopy.Remove('OperationTimeoutSec') # Count the number of options provided for use of displaying a progress bar @@ -236,11 +228,9 @@ Outputs objects representing autoruns entries similar to the output of Sysintern $ComputerName = $Session.ComputerName if (-not $Session.ComputerName) { $ComputerName = 'localhost' } - if (-not $PSBoundParameters['NoProgressBar']) { - # Display a progress activity for each CIM session - Write-Progress -Id 1 -Activity 'CimSweep - Registry autoruns sweep' -Status "($($CurrentCIMSession+1)/$($CIMSessionCount)) Current computer: $ComputerName" -PercentComplete (($CurrentCIMSession / $CIMSessionCount) * 100) - $CurrentCIMSession++ - } + # Display a progress activity for each CIM session + Write-Progress -Id 1 -Activity 'CimSweep - Registry autoruns sweep' -Status "($($CurrentCIMSession+1)/$($CIMSessionCount)) Current computer: $ComputerName" -PercentComplete (($CurrentCIMSession / $CIMSessionCount) * 100) + $CurrentCIMSession++ $CommonArgs = @{} @@ -252,10 +242,8 @@ Outputs objects representing autoruns entries similar to the output of Sysintern if (($PSCmdlet.ParameterSetName -ne 'SpecificCheck') -or $PSBoundParameters['Logon']) { $Category = 'Logon' - if (-not $PSBoundParameters['NoProgressBar']) { - Write-Progress -Id 2 -ParentId 1 -Activity " ($($CurrentAutorunCount+1)/$($AutoRunOptionCount)) Current autoruns type:" -Status $Category -PercentComplete (($CurrentAutorunCount / $AutoRunOptionCount) * 100) - $CurrentAutorunCount++ - } + Write-Progress -Id 2 -ParentId 1 -Activity " ($($CurrentAutorunCount+1)/$($AutoRunOptionCount)) Current autoruns type:" -Status $Category -PercentComplete (($CurrentAutorunCount / $AutoRunOptionCount) * 100) + $CurrentAutorunCount++ Get-CSRegistryValue -Hive HKLM -SubKey 'SYSTEM\CurrentControlSet\Control\Terminal Server\Wds\rdpwd' -ValueName StartupPrograms @CommonArgs @Timeout | New-AutoRunsEntry -Category $Category @@ -318,10 +306,8 @@ Outputs objects representing autoruns entries similar to the output of Sysintern if (($PSCmdlet.ParameterSetName -ne 'SpecificCheck') -or $PSBoundParameters['BootExecute']) { $Category = 'BootExecute' - if (-not $PSBoundParameters['NoProgressBar']) { - Write-Progress -Id 2 -ParentId 1 -Activity " ($($CurrentAutorunCount+1)/$($AutoRunOptionCount)) Current autoruns type:" -Status $Category -PercentComplete (($CurrentAutorunCount / $AutoRunOptionCount) * 100) - $CurrentAutorunCount++ - } + Write-Progress -Id 2 -ParentId 1 -Activity " ($($CurrentAutorunCount+1)/$($AutoRunOptionCount)) Current autoruns type:" -Status $Category -PercentComplete (($CurrentAutorunCount / $AutoRunOptionCount) * 100) + $CurrentAutorunCount++ Get-CSRegistryValue -Hive HKLM -SubKey 'SYSTEM\CurrentControlSet\Control\Session Manager' -ValueNameOnly @CommonArgs @Timeout | Where-Object { ('BootExecute','SetupExecute','Execute','S0InitialCommand') -contains $_.ValueName } | ForEach-Object { @@ -336,10 +322,8 @@ Outputs objects representing autoruns entries similar to the output of Sysintern if (($PSCmdlet.ParameterSetName -ne 'SpecificCheck') -or $PSBoundParameters['PrintMonitors']) { $Category = 'PrintMonitors' - if (-not $PSBoundParameters['NoProgressBar']) { - Write-Progress -Id 2 -ParentId 1 -Activity " ($($CurrentAutorunCount+1)/$($AutoRunOptionCount)) Current autoruns type:" -Status $Category -PercentComplete (($CurrentAutorunCount / $AutoRunOptionCount) * 100) - $CurrentAutorunCount++ - } + Write-Progress -Id 2 -ParentId 1 -Activity " ($($CurrentAutorunCount+1)/$($AutoRunOptionCount)) Current autoruns type:" -Status $Category -PercentComplete (($CurrentAutorunCount / $AutoRunOptionCount) * 100) + $CurrentAutorunCount++ Get-CSRegistryKey -Hive HKLM -SubKey 'SYSTEM\CurrentControlSet\Control\Print\Monitors' @CommonArgs @Timeout | Get-CSRegistryValue -ValueName Driver @Timeout | ForEach-Object { @@ -350,10 +334,8 @@ Outputs objects representing autoruns entries similar to the output of Sysintern if (($PSCmdlet.ParameterSetName -ne 'SpecificCheck') -or $PSBoundParameters['NetworkProviders']) { $Category = 'NetworkProviders' - if (-not $PSBoundParameters['NoProgressBar']) { - Write-Progress -Id 2 -ParentId 1 -Activity " ($($CurrentAutorunCount+1)/$($AutoRunOptionCount)) Current autoruns type:" -Status $Category -PercentComplete (($CurrentAutorunCount / $AutoRunOptionCount) * 100) - $CurrentAutorunCount++ - } + Write-Progress -Id 2 -ParentId 1 -Activity " ($($CurrentAutorunCount+1)/$($AutoRunOptionCount)) Current autoruns type:" -Status $Category -PercentComplete (($CurrentAutorunCount / $AutoRunOptionCount) * 100) + $CurrentAutorunCount++ $NetworkOrder = Get-CSRegistryValue -Hive HKLM -SubKey 'SYSTEM\CurrentControlSet\Control\NetworkProvider\Order' -ValueName ProviderOrder @CommonArgs @Timeout @@ -367,10 +349,8 @@ Outputs objects representing autoruns entries similar to the output of Sysintern if (($PSCmdlet.ParameterSetName -ne 'SpecificCheck') -or $PSBoundParameters['LSAProviders']) { $Category = 'LSAProviders' - if (-not $PSBoundParameters['NoProgressBar']) { - Write-Progress -Id 2 -ParentId 1 -Activity " ($($CurrentAutorunCount+1)/$($AutoRunOptionCount)) Current autoruns type:" -Status $Category -PercentComplete (($CurrentAutorunCount / $AutoRunOptionCount) * 100) - $CurrentAutorunCount++ - } + Write-Progress -Id 2 -ParentId 1 -Activity " ($($CurrentAutorunCount+1)/$($AutoRunOptionCount)) Current autoruns type:" -Status $Category -PercentComplete (($CurrentAutorunCount / $AutoRunOptionCount) * 100) + $CurrentAutorunCount++ $SecProviders = Get-CSRegistryValue -Hive HKLM -SubKey 'SYSTEM\CurrentControlSet\Control\SecurityProviders' @CommonArgs @Timeout $SecProviders | New-AutoRunsEntry -ImagePath "$($SecProviders.ValueContent)" -Category $Category @@ -388,10 +368,8 @@ Outputs objects representing autoruns entries similar to the output of Sysintern if (($PSCmdlet.ParameterSetName -ne 'SpecificCheck') -or $PSBoundParameters['ImageHijacks']) { $Category = 'ImageHijacks' - if (-not $PSBoundParameters['NoProgressBar']) { - Write-Progress -Id 2 -ParentId 1 -Activity " ($($CurrentAutorunCount+1)/$($AutoRunOptionCount)) Current autoruns type:" -Status $Category -PercentComplete (($CurrentAutorunCount / $AutoRunOptionCount) * 100) - $CurrentAutorunCount++ - } + Write-Progress -Id 2 -ParentId 1 -Activity " ($($CurrentAutorunCount+1)/$($AutoRunOptionCount)) Current autoruns type:" -Status $Category -PercentComplete (($CurrentAutorunCount / $AutoRunOptionCount) * 100) + $CurrentAutorunCount++ $CommonKeys = @( 'SOFTWARE\Classes\htmlfile\shell\open\command', @@ -475,10 +453,8 @@ Outputs objects representing autoruns entries similar to the output of Sysintern if (($PSCmdlet.ParameterSetName -ne 'SpecificCheck') -or $PSBoundParameters['AppInit']) { $Category = 'AppInit' - if (-not $PSBoundParameters['NoProgressBar']) { - Write-Progress -Id 2 -ParentId 1 -Activity " ($($CurrentAutorunCount+1)/$($AutoRunOptionCount)) Current autoruns type:" -Status $Category -PercentComplete (($CurrentAutorunCount / $AutoRunOptionCount) * 100) - $CurrentAutorunCount++ - } + Write-Progress -Id 2 -ParentId 1 -Activity " ($($CurrentAutorunCount+1)/$($AutoRunOptionCount)) Current autoruns type:" -Status $Category -PercentComplete (($CurrentAutorunCount / $AutoRunOptionCount) * 100) + $CurrentAutorunCount++ $null,'Wow6432Node\' | ForEach-Object { Get-CSRegistryValue -Hive HKLM -SubKey "SOFTWARE\$($_)Microsoft\Windows NT\CurrentVersion\Windows" -ValueName 'AppInit_DLLs' @CommonArgs @Timeout | @@ -494,10 +470,8 @@ Outputs objects representing autoruns entries similar to the output of Sysintern if (($PSCmdlet.ParameterSetName -ne 'SpecificCheck') -or $PSBoundParameters['KnownDLLs']) { $Category = 'KnownDLLs' - if (-not $PSBoundParameters['NoProgressBar']) { - Write-Progress -Id 2 -ParentId 1 -Activity " ($($CurrentAutorunCount+1)/$($AutoRunOptionCount)) Current autoruns type:" -Status $Category -PercentComplete (($CurrentAutorunCount / $AutoRunOptionCount) * 100) - $CurrentAutorunCount++ - } + Write-Progress -Id 2 -ParentId 1 -Activity " ($($CurrentAutorunCount+1)/$($AutoRunOptionCount)) Current autoruns type:" -Status $Category -PercentComplete (($CurrentAutorunCount / $AutoRunOptionCount) * 100) + $CurrentAutorunCount++ Get-CSRegistryValue -Hive HKLM -SubKey 'SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs' @CommonArgs @Timeout | New-AutoRunsEntry -Category $Category @@ -506,10 +480,8 @@ Outputs objects representing autoruns entries similar to the output of Sysintern if (($PSCmdlet.ParameterSetName -ne 'SpecificCheck') -or $PSBoundParameters['Winlogon']) { $Category = 'Winlogon' - if (-not $PSBoundParameters['NoProgressBar']) { - Write-Progress -Id 2 -ParentId 1 -Activity " ($($CurrentAutorunCount+1)/$($AutoRunOptionCount)) Current autoruns type:" -Status $Category -PercentComplete (($CurrentAutorunCount / $AutoRunOptionCount) * 100) - $CurrentAutorunCount++ - } + Write-Progress -Id 2 -ParentId 1 -Activity " ($($CurrentAutorunCount+1)/$($AutoRunOptionCount)) Current autoruns type:" -Status $Category -PercentComplete (($CurrentAutorunCount / $AutoRunOptionCount) * 100) + $CurrentAutorunCount++ $CmdLine = Get-CSRegistryValue -Hive HKLM -SubKey 'SYSTEM\Setup' -ValueName 'CmdLine' @CommonArgs @Timeout @@ -562,10 +534,6 @@ License: BSD 3-Clause Get-CSStartMenuEntry returns file information for all files present (excluding desktop.ini) in user and system-wide start menus. -.PARAMETER NoProgressBar - -Do not display a progress bar. This parameter is designed to be used with wrapper functions. - .PARAMETER CimSession Specifies the CIM session to use for this cmdlet. Enter a variable that contains the CIM session or a command that creates or gets the CIM session, such as the New-CimSession or Get-CimSession cmdlets. For more information, see about_CimSessions. @@ -604,9 +572,6 @@ If a shortcut is present in the start menu, an instance of a Win32_ShortcutFile [OutputType('Microsoft.Management.Infrastructure.CimInstance#root/cimv2/Win32_ShortcutFile')] [CmdletBinding()] param( - [Switch] - $NoProgressBar, - [Alias('Session')] [ValidateNotNullOrEmpty()] [Microsoft.Management.Infrastructure.CimSession[]] @@ -637,23 +602,21 @@ If a shortcut is present in the start menu, an instance of a Win32_ShortcutFile $ComputerName = $Session.ComputerName if (-not $Session.ComputerName) { $ComputerName = 'localhost' } - if (-not $PSBoundParameters['NoProgressBar']) { - # Display a progress activity for each CIM session - Write-Progress -Id 1 -Activity 'CimSweep - Temp directory sweep' -Status "($($CurrentCIMSession+1)/$($CIMSessionCount)) Current computer: $ComputerName" -PercentComplete (($CurrentCIMSession / $CIMSessionCount) * 100) - $CurrentCIMSession++ - } + # Display a progress activity for each CIM session + Write-Progress -Id 1 -Activity 'CimSweep - Temp directory sweep' -Status "($($CurrentCIMSession+1)/$($CIMSessionCount)) Current computer: $ComputerName" -PercentComplete (($CurrentCIMSession / $CIMSessionCount) * 100) + $CurrentCIMSession++ $CommonArgs = @{} if ($Session.Id) { $CommonArgs['CimSession'] = $Session } - Get-CSShellFolderPath -SystemFolder -FolderName 'Common Startup' -NoProgressBar @CommonArgs @Timeout | ForEach-Object { + Get-CSShellFolderPath -SystemFolder -FolderName 'Common Startup' @CommonArgs @Timeout | ForEach-Object { Get-CSDirectoryListing -DirectoryPath $_.ValueContent -File @CommonArgs @Timeout | Where-Object { $_.FileName -ne 'desktop' -and $_.Extension -ne 'ini' } } - Get-CSShellFolderPath -UserFolder -FolderName 'Startup' -NoProgressBar @CommonArgs @Timeout | ForEach-Object { + Get-CSShellFolderPath -UserFolder -FolderName 'Startup' @CommonArgs @Timeout | ForEach-Object { Get-CSDirectoryListing -DirectoryPath $_.ValueContent -File @CommonArgs @Timeout | Where-Object { $_.FileName -ne 'desktop' -and $_.Extension -ne 'ini' } diff --git a/CimSweep/Defense/SuspiciousFiles.ps1 b/CimSweep/Defense/SuspiciousFiles.ps1 index 3f713b0..a9df314 100644 --- a/CimSweep/Defense/SuspiciousFiles.ps1 +++ b/CimSweep/Defense/SuspiciousFiles.ps1 @@ -11,10 +11,6 @@ License: BSD 3-Clause The ability to remotely query scheduled tasks was not introduced until Windows 8. Get-CSScheduledTaskFile offers the next best thing by simply scanning %SystemRoot%\Windows\Tasks. -.PARAMETER NoProgressBar - -Do not display a progress bar. This parameter is designed to be used with wrapper functions. - .PARAMETER CimSession Specifies the CIM session to use for this cmdlet. Enter a variable that contains the CIM session or a command that creates or gets the CIM session, such as the New-CimSession or Get-CimSession cmdlets. For more information, see about_CimSessions. @@ -49,9 +45,6 @@ Outputs CIM_DataFile instances representing task XML files. [CmdletBinding()] [OutputType('Microsoft.Management.Infrastructure.CimInstance#root/cimv2/CIM_DataFile')] param( - [Switch] - $NoProgressBar, - [Alias('Session')] [ValidateNotNullOrEmpty()] [Microsoft.Management.Infrastructure.CimSession[]] @@ -82,11 +75,9 @@ Outputs CIM_DataFile instances representing task XML files. $ComputerName = $Session.ComputerName if (-not $Session.ComputerName) { $ComputerName = 'localhost' } - if (-not $PSBoundParameters['NoProgressBar']) { - # Display a progress activity for each CIM session - Write-Progress -Id 1 -Activity 'CimSweep - Scheduled task file sweep' -Status "($($CurrentCIMSession+1)/$($CIMSessionCount)) Current computer: $ComputerName" -PercentComplete (($CurrentCIMSession / $CIMSessionCount) * 100) - $CurrentCIMSession++ - } + # Display a progress activity for each CIM session + Write-Progress -Id 1 -Activity 'CimSweep - Scheduled task file sweep' -Status "($($CurrentCIMSession+1)/$($CIMSessionCount)) Current computer: $ComputerName" -PercentComplete (($CurrentCIMSession / $CIMSessionCount) * 100) + $CurrentCIMSession++ $CommonArgs = @{} @@ -104,18 +95,14 @@ Outputs CIM_DataFile instances representing task XML files. Write-Verbose "[$ComputerName] Windows directory task path: $WindowsTaskDir" $WindowsTaskDir, $SystemTaskDir | ForEach-Object { - if (-not $PSBoundParameters['NoProgressBar']) { - Write-Progress -Id 2 -ParentId 1 -Activity "Current directory:" -Status $_ - } + Write-Progress -Id 2 -ParentId 1 -Activity "Current directory:" -Status $_ # List tasks in root directory Get-CSDirectoryListing -DirectoryPath $_ -File @CommonArgs @Timeout # Start by only retrieving directory info recursively. This is a performance enhancement Get-CSDirectoryListing -DirectoryPath $_ -Recurse -Directory -DoNotDetectRecursiveDirs @CommonArgs @Timeout | ForEach-Object { - if (-not $PSBoundParameters['NoProgressBar']) { - Write-Progress -Id 2 -ParentId 1 -Activity "Current directory:" -Status ($_.Name) - } + Write-Progress -Id 2 -ParentId 1 -Activity "Current directory:" -Status ($_.Name) # Get task file information for each subdirectory $_ | Get-CSDirectoryListing -File @CommonArgs @Timeout @@ -153,10 +140,6 @@ Specifies that only system-level shell folders should be retrieved. Specifies that only user-specific shell folders should be retrieved. -.PARAMETER NoProgressBar - -Do not display a progress bar. This parameter is designed to be used with wrapper functions. - .PARAMETER CimSession Specifies the CIM session to use for this cmdlet. Enter a variable that contains the CIM session or a command that creates or gets the CIM session, such as the New-CimSession or Get-CimSession cmdlets. For more information, see about_CimSessions. @@ -241,9 +224,6 @@ Outputs a list of registry values representing shell folder paths. [Switch] $UserFolder, - [Switch] - $NoProgressBar, - [Parameter(ParameterSetName = 'Default')] [Parameter(ParameterSetName = 'System')] [Parameter(ParameterSetName = 'User')] @@ -276,14 +256,12 @@ Outputs a list of registry values representing shell folder paths. PROCESS { foreach ($Session in $CimSession) { - if (-not $PSBoundParameters['NoProgressBar']) { - $ComputerName = $Session.ComputerName - if (-not $Session.ComputerName) { $ComputerName = 'localhost' } + $ComputerName = $Session.ComputerName + if (-not $Session.ComputerName) { $ComputerName = 'localhost' } - # Display a progress activity for each CIM session - Write-Progress -Id 1 -Activity 'CimSweep - Shell folder path sweep' -Status "($($CurrentCIMSession+1)/$($CIMSessionCount)) Current computer: $ComputerName" -PercentComplete (($CurrentCIMSession / $CIMSessionCount) * 100) - $CurrentCIMSession++ - } + # Display a progress activity for each CIM session + Write-Progress -Id 1 -Activity 'CimSweep - Shell folder path sweep' -Status "($($CurrentCIMSession+1)/$($CIMSessionCount)) Current computer: $ComputerName" -PercentComplete (($CurrentCIMSession / $CIMSessionCount) * 100) + $CurrentCIMSession++ $CommonArgs = @{} @@ -354,10 +332,6 @@ Specifies that only system-level temp directories should be retrieved. Specifies that only user-specific temp directories should be retrieved. -.PARAMETER NoProgressBar - -Do not display a progress bar. This parameter is designed to be used with wrapper functions. - .PARAMETER DoNotRecurse Only list files in the root directory. @@ -423,12 +397,6 @@ Outputs CIM_DataFile instances of files present in the specified temp directory [Switch] $DoNotRecurse, - [Parameter(ParameterSetName = 'Default')] - [Parameter(ParameterSetName = 'System')] - [Parameter(ParameterSetName = 'User')] - [Switch] - $NoProgressBar, - [Parameter(ParameterSetName = 'Default')] [Parameter(ParameterSetName = 'System')] [Parameter(ParameterSetName = 'User')] @@ -465,11 +433,9 @@ Outputs CIM_DataFile instances of files present in the specified temp directory $ComputerName = $Session.ComputerName if (-not $Session.ComputerName) { $ComputerName = 'localhost' } - if (-not $PSBoundParameters['NoProgressBar']) { - # Display a progress activity for each CIM session - Write-Progress -Id 1 -Activity 'CimSweep - Temp directory sweep' -Status "($($CurrentCIMSession+1)/$($CIMSessionCount)) Current computer: $ComputerName" -PercentComplete (($CurrentCIMSession / $CIMSessionCount) * 100) - $CurrentCIMSession++ - } + # Display a progress activity for each CIM session + Write-Progress -Id 1 -Activity 'CimSweep - Temp directory sweep' -Status "($($CurrentCIMSession+1)/$($CIMSessionCount)) Current computer: $ComputerName" -PercentComplete (($CurrentCIMSession / $CIMSessionCount) * 100) + $CurrentCIMSession++ $CommonArgs = @{} @@ -477,23 +443,19 @@ Outputs CIM_DataFile instances of files present in the specified temp directory if (($PSCmdlet.ParameterSetName -eq 'System') -or ($PSCmdlet.ParameterSetName -eq 'Default')) { # Get system temp path from the registry - $SystemTempPath = Get-CSEnvironmentVariable -SystemVariable -VariableName TEMP -NoProgressBar @CommonArgs @Timeout + $SystemTempPath = Get-CSEnvironmentVariable -SystemVariable -VariableName TEMP @CommonArgs @Timeout if ($SystemTempPath.VariableValue) { Write-Verbose "[$ComputerName] User temp directory: $($SystemTempPath.VariableValue)" - if (-not $PSBoundParameters['NoProgressBar']) { - Write-Progress -Id 2 -ParentId 1 -Activity "Current directory:" -Status $SystemTempPath.VariableValue - } + Write-Progress -Id 2 -ParentId 1 -Activity "Current directory:" -Status $SystemTempPath.VariableValue # Display files in the root temp dir Get-CSDirectoryListing -DirectoryPath $SystemTempPath.VariableValue -File @TargetExtensions @CommonArgs @Timeout if (-not $PSBoundParameters['DoNotRecurse']) { Get-CSDirectoryListing -DirectoryPath $SystemTempPath.VariableValue -Directory -Recurse @CommonArgs @Timeout | ForEach-Object { - if (-not $PSBoundParameters['NoProgressBar']) { - Write-Progress -Id 2 -ParentId 1 -Activity "Current directory:" -Status ($_.Name) - } + Write-Progress -Id 2 -ParentId 1 -Activity "Current directory:" -Status ($_.Name) $_ | Get-CSDirectoryListing -File @TargetExtensions @Timeout } @@ -505,8 +467,8 @@ Outputs CIM_DataFile instances of files present in the specified temp directory if (($PSCmdlet.ParameterSetName -eq 'User') -or ($PSCmdlet.ParameterSetName -eq 'Default')) { # Get user %USERPROFILE% and validate the end of %TEMP%. The root path of %TEMP% is not often not resolved properly. - $UserProfiles = Get-CSEnvironmentVariable -UserVariable -VariableName USERPROFILE -NoProgressBar @CommonArgs @Timeout - $TempVars = Get-CSEnvironmentVariable -UserVariable -VariableName TEMP -NoProgressBar @CommonArgs @Timeout + $UserProfiles = Get-CSEnvironmentVariable -UserVariable -VariableName USERPROFILE @CommonArgs @Timeout + $TempVars = Get-CSEnvironmentVariable -UserVariable -VariableName TEMP @CommonArgs @Timeout foreach ($UserProfile in $UserProfiles) { $TempVars | Where-Object { $_.User -eq $UserProfile.User } | ForEach-Object { @@ -528,18 +490,14 @@ Outputs CIM_DataFile instances of files present in the specified temp directory if ($ExpectedPathObtained) { Write-Verbose "[$ComputerName] User temp directory: $FullTempPath" - if (-not $PSBoundParameters['NoProgressBar']) { - Write-Progress -Id 2 -ParentId 1 -Activity "Current directory:" -Status $FullTempPath - } + Write-Progress -Id 2 -ParentId 1 -Activity "Current directory:" -Status $FullTempPath # Display files in the root temp dir Get-CSDirectoryListing -DirectoryPath $FullTempPath -File @TargetExtensions @CommonArgs @Timeout if (-not $PSBoundParameters['DoNotRecurse']) { Get-CSDirectoryListing -DirectoryPath $FullTempPath -Directory -Recurse @CommonArgs @Timeout | ForEach-Object { - if (-not $PSBoundParameters['NoProgressBar']) { - Write-Progress -Id 2 -ParentId 1 -Activity "Current directory:" -Status ($_.Name) - } + Write-Progress -Id 2 -ParentId 1 -Activity "Current directory:" -Status ($_.Name) $_ | Get-CSDirectoryListing -File @TargetExtensions @Timeout } @@ -569,10 +527,6 @@ Get-CSLowILPathFile lists files present in user low-integrity folders. This can Specifies that only files of a certain extension should be returned. When specifying extensions, do not include a dot - e.g. 'exe', 'dll', 'sys'. -.PARAMETER NoProgressBar - -Do not display a progress bar. This parameter is designed to be used with wrapper functions. - .PARAMETER DoNotRecurse Only list files in the root directory. @@ -618,9 +572,6 @@ Outputs CIM_DataFile instances of files present in low-integrity level directori [Switch] $DoNotRecurse, - [Switch] - $NoProgressBar, - [Parameter(ValueFromPipeline = $True)] [Alias('Session')] [ValidateNotNullOrEmpty()] @@ -655,34 +606,28 @@ Outputs CIM_DataFile instances of files present in low-integrity level directori $ComputerName = $Session.ComputerName if (-not $Session.ComputerName) { $ComputerName = 'localhost' } - if (-not $PSBoundParameters['NoProgressBar']) { - # Display a progress activity for each CIM session - Write-Progress -Id 1 -Activity 'CimSweep - Low integrity level directory sweep' -Status "($($CurrentCIMSession+1)/$($CIMSessionCount)) Current computer: $ComputerName" -PercentComplete (($CurrentCIMSession / $CIMSessionCount) * 100) - $CurrentCIMSession++ - } + # Display a progress activity for each CIM session + Write-Progress -Id 1 -Activity 'CimSweep - Low integrity level directory sweep' -Status "($($CurrentCIMSession+1)/$($CIMSessionCount)) Current computer: $ComputerName" -PercentComplete (($CurrentCIMSession / $CIMSessionCount) * 100) + $CurrentCIMSession++ $CommonArgs = @{} if ($Session.Id) { $CommonArgs['CimSession'] = $Session } - Get-CSEnvironmentVariable -UserVariable -VariableName LOCALAPPDATA -NoProgressBar @CommonArgs @Timeout | ForEach-Object { + Get-CSEnvironmentVariable -UserVariable -VariableName LOCALAPPDATA @CommonArgs @Timeout | ForEach-Object { Write-Verbose "[$ComputerName] LocalAppData path: $($_.VariableValue)" if ($_.VariableValue) { $LocalLowPath = "$($_.VariableValue)Low" - if (-not $PSBoundParameters['NoProgressBar']) { - Write-Progress -Id 2 -ParentId 1 -Activity "Current directory:" -Status $LocalLowPath - } + Write-Progress -Id 2 -ParentId 1 -Activity "Current directory:" -Status $LocalLowPath # List all files in the root low IL dir Get-CSDirectoryListing -DirectoryPath $LocalLowPath -File @TargetExtensions @CommonArgs @Timeout if (-not $PSBoundParameters['DoNotRecurse']) { Get-CSDirectoryListing -DirectoryPath $LocalLowPath -Recurse -Directory @CommonArgs @Timeout | ForEach-Object { - if (-not $PSBoundParameters['NoProgressBar']) { - Write-Progress -Id 2 -ParentId 1 -Activity "Current directory:" -Status ($_.Name) - } + Write-Progress -Id 2 -ParentId 1 -Activity "Current directory:" -Status ($_.Name) $_ | Get-CSDirectoryListing -File @TargetExtensions @Timeout } diff --git a/CimSweep/Defense/SuspiciousURLs.ps1 b/CimSweep/Defense/SuspiciousURLs.ps1 index 4e8a892..ca9af2d 100644 --- a/CimSweep/Defense/SuspiciousURLs.ps1 +++ b/CimSweep/Defense/SuspiciousURLs.ps1 @@ -11,10 +11,6 @@ License: BSD 3-Clause Get-CSTypedURL retrieves URLs that were typed into the Internet Explorer URL bar. -.PARAMETER NoProgressBar - -Do not display a progress bar. This parameter is designed to be used with wrapper functions. - .PARAMETER CimSession Specifies the CIM session to use for this cmdlet. Enter a variable that contains the CIM session or a command that creates or gets the CIM session, such as the New-CimSession or Get-CimSession cmdlets. For more information, see about_CimSessions. @@ -49,9 +45,6 @@ Outputs the registry values consisting of typed IE URLs. [CmdletBinding()] [OutputType('CimSweep.RegistryValue')] param( - [Switch] - $NoProgressBar, - [Alias('Session')] [ValidateNotNullOrEmpty()] [Microsoft.Management.Infrastructure.CimSession[]] @@ -82,11 +75,9 @@ Outputs the registry values consisting of typed IE URLs. $ComputerName = $Session.ComputerName if (-not $Session.ComputerName) { $ComputerName = 'localhost' } - if (-not $PSBoundParameters['NoProgressBar']) { - # Display a progress activity for each CIM session - Write-Progress -Id 1 -Activity 'CimSweep - Internet Explorer typed URL sweep' -Status "($($CurrentCIMSession+1)/$($CIMSessionCount)) Current computer: $ComputerName" -PercentComplete (($CurrentCIMSession / $CIMSessionCount) * 100) - $CurrentCIMSession++ - } + # Display a progress activity for each CIM session + Write-Progress -Id 1 -Activity 'CimSweep - Internet Explorer typed URL sweep' -Status "($($CurrentCIMSession+1)/$($CIMSessionCount)) Current computer: $ComputerName" -PercentComplete (($CurrentCIMSession / $CIMSessionCount) * 100) + $CurrentCIMSession++ $CommonArgs = @{} diff --git a/CimSweep/Offense/ACLAudits.ps1 b/CimSweep/Offense/ACLAudits.ps1 index a6d401b..4b462cb 100644 --- a/CimSweep/Offense/ACLAudits.ps1 +++ b/CimSweep/Offense/ACLAudits.ps1 @@ -15,10 +15,6 @@ Get-CSVulnerableServicePermission is used to perform service ACL audits at scale Specifies that driver file permissions should be queried in addition to user-mode services. Read the notes section for more information about the limitations of driver audits. -.PARAMETER NoProgressBar - -Do not display a progress bar. This parameter is designed to be used with wrapper functions. - .PARAMETER CimSession Specifies the CIM session to use for this cmdlet. Enter a variable that contains the CIM session or a command that creates or gets the CIM session, such as the New-CimSession or Get-CimSession cmdlets. For more information, see about_CimSessions. @@ -56,9 +52,6 @@ Service ACL sweep across a large amount of hosts will take a long time. [Switch] $IncludeDrivers, - [Switch] - $NoProgressBar, - [Alias('Session')] [ValidateNotNullOrEmpty()] [Microsoft.Management.Infrastructure.CimSession[]] @@ -93,11 +86,9 @@ Service ACL sweep across a large amount of hosts will take a long time. $ComputerName = $Session.ComputerName if (-not $Session.ComputerName) { $ComputerName = 'localhost' } - if (-not $PSBoundParameters['NoProgressBar']) { - # Display a progress activity for each CIM session - Write-Progress -Id 1 -Activity 'CimSweep - Service ACL sweep' -Status "($($CurrentCIMSession+1)/$($CIMSessionCount)) Current computer: $ComputerName" -PercentComplete (($CurrentCIMSession / $CIMSessionCount) * 100) - $CurrentCIMSession++ - } + # Display a progress activity for each CIM session + Write-Progress -Id 1 -Activity 'CimSweep - Service ACL sweep' -Status "($($CurrentCIMSession+1)/$($CIMSessionCount)) Current computer: $ComputerName" -PercentComplete (($CurrentCIMSession / $CIMSessionCount) * 100) + $CurrentCIMSession++ $CommonArgs = @{} @@ -105,12 +96,10 @@ Service ACL sweep across a large amount of hosts will take a long time. $UserGrouping = @{} - Get-CSService -NoProgressBar -IncludeAcl -IncludeFileInfo @UserModeServices @CommonArgs @Timeout | ForEach-Object { + Get-CSService -IncludeAcl -IncludeFileInfo @UserModeServices @CommonArgs @Timeout | ForEach-Object { $ServiceName = $_.Name - if (-not $PSBoundParameters['NoProgressBar']) { - Write-Progress -Id 2 -ParentId 1 -Activity " Current service:" -Status $ServiceName - } + Write-Progress -Id 2 -ParentId 1 -Activity " Current service:" -Status $ServiceName foreach ($FileDACL in $_.FileInfo.ACL.Access) { $GroupName = $FileDACL.IdentityReference.ToString() diff --git a/CimSweep/Tests/Core.CimSweep.Tests.ps1 b/CimSweep/Tests/Core.CimSweep.Tests.ps1 index d27240c..ddd0916 100644 --- a/CimSweep/Tests/Core.CimSweep.Tests.ps1 +++ b/CimSweep/Tests/Core.CimSweep.Tests.ps1 @@ -1,5 +1,7 @@ Set-StrictMode -Version Latest +$ProgressPreference = 'Continue' + $TestScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent $ModuleRoot = Resolve-Path "$TestScriptRoot\.." $ModuleManifest = "$ModuleRoot\CimSweep.psd1" @@ -329,28 +331,28 @@ Describe 'Get-CSRegistryValue' { Describe 'Get-CSEventLog' { It 'should return output' { - $Result = Get-CSEventLog -NoProgressBar | Select -First 1 + $Result = Get-CSEventLog | Select -First 1 $Result.LogName | Should Not BeNullOrEmpty $Result.PSComputerName | Should BeNullOrEmpty } It 'should return output with CIM sessions' { - $Result = Get-CSEventLog -NoProgressBar -CimSession $TestSessionArray | Select -First 1 + $Result = Get-CSEventLog -CimSession $TestSessionArray | Select -First 1 $Result.LogName | Should Not BeNullOrEmpty $Result.PSComputerName | Should BeExactly 'localhost' } It 'should return output and accept -OperationTimeoutSec' { - $Result = Get-CSEventLog -NoProgressBar -OperationTimeoutSec 3 | Select -First 1 + $Result = Get-CSEventLog -OperationTimeoutSec 3 | Select -First 1 $Result.LogName | Should Not BeNullOrEmpty $Result.PSComputerName | Should BeNullOrEmpty } It 'should return output with CIM sessions and accept -OperationTimeoutSec' { - $Result = Get-CSEventLog -NoProgressBar -CimSession $TestSessionArray -OperationTimeoutSec 3 | Select -First 1 + $Result = Get-CSEventLog -CimSession $TestSessionArray -OperationTimeoutSec 3 | Select -First 1 $Result.LogName | Should Not BeNullOrEmpty $Result.PSComputerName | Should BeExactly 'localhost' @@ -359,39 +361,39 @@ Describe 'Get-CSEventLog' { Describe 'Get-CSEventLogEntry' { It 'should return nothing upon receiving an undefined entry type' { - { Get-CSEventLogEntry -EntryType Undefined -NoProgressBar } | Should Throw + { Get-CSEventLogEntry -EntryType Undefined } | Should Throw } It 'should accept all valid event entry types' { - { Get-CSEventLogEntry -EntryType Error -NoProgressBar | Select-Object -First 1 } | Should Not Throw - { Get-CSEventLogEntry -EntryType Warning -CimSession $TestCimSession1 -NoProgressBar | Select-Object -First 1 } | Should Not Throw + { Get-CSEventLogEntry -EntryType Error | Select-Object -First 1 } | Should Not Throw + { Get-CSEventLogEntry -EntryType Warning -CimSession $TestCimSession1 | Select-Object -First 1 } | Should Not Throw } It 'should return Win32_NtLogEvent instances' { - $Event = Get-CSEventLogEntry -NoProgressBar | Select-Object -First 1 + $Event = Get-CSEventLogEntry | Select-Object -First 1 $Event.PSObject.TypeNames[0] | Should BeExactly 'Microsoft.Management.Infrastructure.CimInstance#root/cimv2/Win32_NTLogEvent' } It 'should return nothing when it receives a non-existent LogName' { - Get-CSEventLogEntry -LogName NonExistentLog -NoProgressBar | Should BeNullOrEmpty + Get-CSEventLogEntry -LogName NonExistentLog | Should BeNullOrEmpty } It 'should return results when no LogName is specified (i.e. all logs implied)' { - $SystemEvent = Get-CSEventLogEntry -NoProgressBar | Select-Object -First 1 + $SystemEvent = Get-CSEventLogEntry | Select-Object -First 1 $SystemEvent | Should Not BeNullOrEmpty $SystemEvent.LogFile | Should Not BeNullOrEmpty $SystemEvent.PSComputerName | Should BeNullOrEmpty } It 'should return results when no LogName is specified (i.e. all logs implied) w/ CIM sessions' { - $SystemEvent = Get-CSEventLogEntry -CimSession $TestCimSession1 -NoProgressBar | Select-Object -First 1 + $SystemEvent = Get-CSEventLogEntry -CimSession $TestCimSession1 | Select-Object -First 1 $SystemEvent | Should Not BeNullOrEmpty $SystemEvent.LogFile | Should Not BeNullOrEmpty $SystemEvent.PSComputerName | Should BeExactly 'localhost' } It 'should return a System log entry' { - $SystemEvent = Get-CSEventLogEntry -LogName System -NoProgressBar | Select-Object -First 1 + $SystemEvent = Get-CSEventLogEntry -LogName System | Select-Object -First 1 $SystemEvent | Should Not BeNullOrEmpty $SystemEvent.LogFile | Should BeExactly 'System' @@ -399,9 +401,9 @@ Describe 'Get-CSEventLogEntry' { } It 'should accept output from Get-CSEventLog' { - $SystemEvent = Get-CSEventLog -NoProgressBar | + $SystemEvent = Get-CSEventLog | Where-Object { $_.LogName -eq 'System' } | - Get-CSEventLogEntry -NoProgressBar | Select-Object -First 1 + Get-CSEventLogEntry | Select-Object -First 1 $SystemEvent | Should Not BeNullOrEmpty $SystemEvent.LogFile | Should BeExactly 'System' @@ -409,7 +411,7 @@ Describe 'Get-CSEventLogEntry' { } It 'should return a System log entry w/ CIM sessions' { - $SystemEvent = Get-CSEventLogEntry -LogName System -CimSession $TestCimSession1 -NoProgressBar | + $SystemEvent = Get-CSEventLogEntry -LogName System -CimSession $TestCimSession1 | Select-Object -First 1 $SystemEvent | Should Not BeNullOrEmpty @@ -418,9 +420,9 @@ Describe 'Get-CSEventLogEntry' { } It 'should accept output from Get-CSEventLog w/ CIM sessions' { - $SystemEvent = Get-CSEventLog -CimSession $TestCimSession1 -NoProgressBar | + $SystemEvent = Get-CSEventLog -CimSession $TestCimSession1 | Where-Object { $_.LogName -eq 'System' } | - Get-CSEventLogEntry -NoProgressBar | Select-Object -First 1 + Get-CSEventLogEntry | Select-Object -First 1 $SystemEvent | Should Not BeNullOrEmpty $SystemEvent.LogFile | Should BeExactly 'System' @@ -428,7 +430,7 @@ Describe 'Get-CSEventLogEntry' { } It 'should return a System log entry with stripped properties when -LimitOutput is provided' { - $SystemEvent = Get-CSEventLogEntry -LogName System -LimitOutput -NoProgressBar | + $SystemEvent = Get-CSEventLogEntry -LogName System -LimitOutput | Select-Object -First 1 $SystemEvent | Should Not BeNullOrEmpty @@ -439,7 +441,7 @@ Describe 'Get-CSEventLogEntry' { } It 'should return a log entry with only the LogFile property present' { - $SystemEvent = Get-CSEventLogEntry -Property Logfile -NoProgressBar | + $SystemEvent = Get-CSEventLogEntry -Property Logfile | Select-Object -First 1 $SystemEvent | Should Not BeNullOrEmpty @@ -450,7 +452,7 @@ Describe 'Get-CSEventLogEntry' { } It 'should return a log entry with only the LogFile property present w/ CIM sessions' { - $SystemEvent = Get-CSEventLogEntry -Property Logfile -CimSession $TestCimSession1 -NoProgressBar | + $SystemEvent = Get-CSEventLogEntry -Property Logfile -CimSession $TestCimSession1 | Select-Object -First 1 $SystemEvent | Should Not BeNullOrEmpty @@ -461,7 +463,7 @@ Describe 'Get-CSEventLogEntry' { } It 'should return a System log entry with stripped properties when -LimitOutput is provided w/ CIM sessions' { - $SystemEvent = Get-CSEventLogEntry -LogName System -CimSession $TestCimSession1 -LimitOutput -NoProgressBar | + $SystemEvent = Get-CSEventLogEntry -LogName System -CimSession $TestCimSession1 -LimitOutput | Select-Object -First 1 $SystemEvent | Should Not BeNullOrEmpty @@ -765,49 +767,49 @@ Describe 'Get-CSService' { $Win32SystemDriverType = 'Microsoft.Management.Infrastructure.CimInstance#root/cimv2/Win32_SystemDriver' It 'should return Win32_BaseService instances' { - $Service = Get-CSService -NoProgressBar | Select-Object -First 1 + $Service = Get-CSService | Select-Object -First 1 $Service | Should Not BeNullOrEmpty $Service.PSObject.TypeNames | Where-Object { $_ -eq $BaseServiceWMIType } | Should BeExactly $BaseServiceWMIType $Service.PSComputerName | Should BeNullOrEmpty } It 'should return Win32_BaseService instances w/ CIM sessions' { - $Service = Get-CSService -NoProgressBar -CimSession $TestCimSession1 | Select-Object -First 1 + $Service = Get-CSService -CimSession $TestCimSession1 | Select-Object -First 1 $Service | Should Not BeNullOrEmpty $Service.PSObject.TypeNames | Where-Object { $_ -eq $BaseServiceWMIType } | Should Be $BaseServiceWMIType $Service.PSComputerName | Should BeExactly 'localhost' } It 'should return kernel driver instances' { - $Service = Get-CSService -NoProgressBar -ServiceType 'Kernel Driver' | Select-Object -First 1 + $Service = Get-CSService -ServiceType 'Kernel Driver' | Select-Object -First 1 $Service | Should Not BeNullOrEmpty $Service.PSObject.TypeNames[0] | Should BeExactly $Win32SystemDriverType $Service.PSComputerName | Should BeNullOrEmpty } It 'should return kernel driver instances w/ CIM sessions' { - $Service = Get-CSService -NoProgressBar -ServiceType 'Kernel Driver' -CimSession $TestCimSession1 | Select-Object -First 1 + $Service = Get-CSService -ServiceType 'Kernel Driver' -CimSession $TestCimSession1 | Select-Object -First 1 $Service | Should Not BeNullOrEmpty $Service.PSObject.TypeNames[0] | Should BeExactly $Win32SystemDriverType $Service.PSComputerName | Should BeExactly 'localhost' } It 'should return user mode service instances' { - $Service = Get-CSService -NoProgressBar -ServiceType 'Share Process' | Select-Object -First 1 + $Service = Get-CSService -ServiceType 'Share Process' | Select-Object -First 1 $Service | Should Not BeNullOrEmpty $Service.PSObject.TypeNames[0] | Should BeExactly $Win32ServiceType $Service.PSComputerName | Should BeNullOrEmpty } It 'should return user mode service instances w/ CIM sessions' { - $Service = Get-CSService -NoProgressBar -ServiceType 'Share Process' -CimSession $TestCimSession1 | Select-Object -First 1 + $Service = Get-CSService -ServiceType 'Share Process' -CimSession $TestCimSession1 | Select-Object -First 1 $Service | Should Not BeNullOrEmpty $Service.PSObject.TypeNames[0] | Should BeExactly $Win32ServiceType $Service.PSComputerName | Should BeExactly 'localhost' } It 'should return a running service' { - $Service = Get-CSService -NoProgressBar -State Running | Select-Object -First 1 + $Service = Get-CSService -State Running | Select-Object -First 1 $Service | Should Not BeNullOrEmpty $Service.PSObject.TypeNames | Where-Object { $_ -eq $BaseServiceWMIType } | Should BeExactly $BaseServiceWMIType $Service.State | Should BeExactly 'Running' @@ -825,7 +827,7 @@ Describe 'Get-CSService' { } It 'should return a running service w/ CIM sessions' { - $Service = Get-CSService -NoProgressBar -State Running -CimSession $TestCimSession1 | Select-Object -First 1 + $Service = Get-CSService -State Running -CimSession $TestCimSession1 | Select-Object -First 1 $Service | Should Not BeNullOrEmpty $Service.PSObject.TypeNames | Where-Object { $_ -eq $BaseServiceWMIType } | Should Be $BaseServiceWMIType $Service.State | Should BeExactly 'Running' @@ -833,13 +835,13 @@ Describe 'Get-CSService' { } It 'should limit the output of its properties to a default set' { - $Service = Get-CSService -NoProgressBar -LimitOutput | Select-Object -First 1 + $Service = Get-CSService -LimitOutput | Select-Object -First 1 $Service | Should Not BeNullOrEmpty $Service.PSObject.TypeNames | Where-Object { $_ -eq $BaseServiceWMIType } | Should Be $BaseServiceWMIType $Service.StartMode | Should BeNullOrEmpty $Service.PSComputerName | Should BeNullOrEmpty - $Service = Get-CSService -NoProgressBar | Select-Object -First 1 + $Service = Get-CSService | Select-Object -First 1 $Service | Should Not BeNullOrEmpty $Service.PSObject.TypeNames | Where-Object { $_ -eq $BaseServiceWMIType } | Should Be $BaseServiceWMIType $Service.StartMode | Should Not BeNullOrEmpty @@ -847,13 +849,13 @@ Describe 'Get-CSService' { } It 'should limit the output of its properties to a default set w/ CIM sessions' { - $Service = Get-CSService -NoProgressBar -LimitOutput -CimSession $TestCimSession1 | Select-Object -First 1 + $Service = Get-CSService -LimitOutput -CimSession $TestCimSession1 | Select-Object -First 1 $Service | Should Not BeNullOrEmpty $Service.PSObject.TypeNames | Where-Object { $_ -eq $BaseServiceWMIType } | Should Be $BaseServiceWMIType $Service.StartMode | Should BeNullOrEmpty $Service.PSComputerName | Should BeExactly 'localhost' - $Service = Get-CSService -NoProgressBar -CimSession $TestCimSession1 | Select-Object -First 1 + $Service = Get-CSService -CimSession $TestCimSession1 | Select-Object -First 1 $Service | Should Not BeNullOrEmpty $Service.PSObject.TypeNames | Where-Object { $_ -eq $BaseServiceWMIType } | Should Be $BaseServiceWMIType $Service.StartMode | Should Not BeNullOrEmpty @@ -861,7 +863,7 @@ Describe 'Get-CSService' { } It 'should only include the specified property' { - $Service = Get-CSService -NoProgressBar -Property Name | Select-Object -First 1 + $Service = Get-CSService -Property Name | Select-Object -First 1 $Service | Should Not BeNullOrEmpty $Service.PSObject.TypeNames | Where-Object { $_ -eq $BaseServiceWMIType } | Should Be $BaseServiceWMIType $Service.Name | Should Not BeNullOrEmpty @@ -870,7 +872,7 @@ Describe 'Get-CSService' { } It 'should only include the specified property w/ CIM sessions' { - $Service = Get-CSService -NoProgressBar -Property Name -CimSession $TestCimSession1 | Select-Object -First 1 + $Service = Get-CSService -Property Name -CimSession $TestCimSession1 | Select-Object -First 1 $Service | Should Not BeNullOrEmpty $Service.PSObject.TypeNames | Where-Object { $_ -eq $BaseServiceWMIType } | Should Be $BaseServiceWMIType $Service.Name | Should Not BeNullOrEmpty @@ -883,15 +885,15 @@ Describe 'Get-CSProcess' { $ProcessWMIType = 'Microsoft.Management.Infrastructure.CimInstance#ROOT/cimv2/Win32_Process' It 'should return nothing when a nonexistent process name is specified' { - Get-CSProcess -Name nonexistentprocess -NoProgressBar | Should BeNullOrEmpty + Get-CSProcess -Name nonexistentprocess | Should BeNullOrEmpty } It 'should return nothing when a nonexistent process name is specified w/ CIM sessions' { - Get-CSProcess -Name nonexistentprocess -CimSession $TestCimSession1 -NoProgressBar | Should BeNullOrEmpty + Get-CSProcess -Name nonexistentprocess -CimSession $TestCimSession1 | Should BeNullOrEmpty } It 'should return the system process' { - $Process = Get-CSProcess -NoProgressBar -Name System -ProcessID 4 | Select-Object -First 1 + $Process = Get-CSProcess -Name System -ProcessID 4 | Select-Object -First 1 $Process | Should Not BeNullOrEmpty $Process.PSObject.TypeNames[0] | Should Be $ProcessWMIType $Process.Name | Should BeExactly 'System' @@ -900,7 +902,7 @@ Describe 'Get-CSProcess' { } It 'should return the system process w/ CIM sessions' { - $Process = Get-CSProcess -NoProgressBar -Name System -ProcessID 4 -CimSession $TestCimSession1 | Select-Object -First 1 + $Process = Get-CSProcess -Name System -ProcessID 4 -CimSession $TestCimSession1 | Select-Object -First 1 $Process | Should Not BeNullOrEmpty $Process.PSObject.TypeNames[0] | Should Be $ProcessWMIType $Process.Name | Should BeExactly 'System' @@ -910,7 +912,7 @@ Describe 'Get-CSProcess' { It 'should return a child process of the system process' { # This should always be smss.exe - $Process = Get-CSProcess -NoProgressBar -ParentProcessId 4 | Select-Object -First 1 + $Process = Get-CSProcess -ParentProcessId 4 | Select-Object -First 1 $Process | Should Not BeNullOrEmpty $Process.PSObject.TypeNames[0] | Should Be $ProcessWMIType $Process.PSComputerName | Should BeNullOrEmpty @@ -918,35 +920,35 @@ Describe 'Get-CSProcess' { It 'should return a child process of the system process w/ CIM sessions' { # This should always be smss.exe - $Process = Get-CSProcess -NoProgressBar -ParentProcessId 4 -CimSession $TestCimSession1 | Select-Object -First 1 + $Process = Get-CSProcess -ParentProcessId 4 -CimSession $TestCimSession1 | Select-Object -First 1 $Process | Should Not BeNullOrEmpty $Process.PSObject.TypeNames[0] | Should Be $ProcessWMIType $Process.PSComputerName | Should BeExactly 'localhost' } It 'should return a process instance' { - $Process = Get-CSProcess -NoProgressBar | Select-Object -First 1 + $Process = Get-CSProcess | Select-Object -First 1 $Process | Should Not BeNullOrEmpty $Process.PSObject.TypeNames[0] | Should Be $ProcessWMIType $Process.PSComputerName | Should BeNullOrEmpty } It 'should return a process instance w/ CIM sessions' { - $Process = Get-CSProcess -NoProgressBar -CimSession $TestCimSession1 | Select-Object -First 1 + $Process = Get-CSProcess -CimSession $TestCimSession1 | Select-Object -First 1 $Process | Should Not BeNullOrEmpty $Process.PSObject.TypeNames[0] | Should Be $ProcessWMIType $Process.PSComputerName | Should BeExactly 'localhost' } It 'should limit the output of its properties to a default set' { - $Process = Get-CSProcess -NoProgressBar -LimitOutput | Select-Object -First 1 + $Process = Get-CSProcess -LimitOutput | Select-Object -First 1 $Process | Should Not BeNullOrEmpty $Process.PSObject.TypeNames -contains $ProcessWMIType | Should Be $True $Process.VM | Should BeNullOrEmpty $Process.Name | Should Not BeNullOrEmpty $Process.PSComputerName | Should BeNullOrEmpty - $Process = Get-CSProcess -NoProgressBar | Select-Object -First 1 + $Process = Get-CSProcess | Select-Object -First 1 $Process | Should Not BeNullOrEmpty $Process.PSObject.TypeNames -contains $ProcessWMIType | Should Be $True $Process.VM | Should Not BeNullOrEmpty @@ -955,14 +957,14 @@ Describe 'Get-CSProcess' { } It 'should limit the output of its properties to a default set w/ CIM sessions' { - $Process = Get-CSProcess -NoProgressBar -LimitOutput -CimSession $TestCimSession1 | Select-Object -First 1 + $Process = Get-CSProcess -LimitOutput -CimSession $TestCimSession1 | Select-Object -First 1 $Process | Should Not BeNullOrEmpty $Process.PSObject.TypeNames -contains $ProcessWMIType | Should Be $True $Process.VM | Should BeNullOrEmpty $Process.Name | Should Not BeNullOrEmpty $Process.PSComputerName | Should BeExactly 'localhost' - $Process = Get-CSProcess -NoProgressBar -CimSession $TestCimSession1 | Select-Object -First 1 + $Process = Get-CSProcess -CimSession $TestCimSession1 | Select-Object -First 1 $Process | Should Not BeNullOrEmpty $Process.PSObject.TypeNames -contains $ProcessWMIType | Should Be $True $Process.VM | Should Not BeNullOrEmpty @@ -971,7 +973,7 @@ Describe 'Get-CSProcess' { } It 'should only include the specified property' { - $Process = Get-CSProcess -NoProgressBar -Property Name | Select-Object -First 1 + $Process = Get-CSProcess -Property Name | Select-Object -First 1 $Process | Should Not BeNullOrEmpty $Process.PSObject.TypeNames -contains $ProcessWMIType | Should Be $True $Process.VM | Should BeNullOrEmpty @@ -980,7 +982,7 @@ Describe 'Get-CSProcess' { } It 'should only include the specified property w/ CIM sessions' { - $Process = Get-CSProcess -NoProgressBar -Property Name -CimSession $TestCimSession1 | Select-Object -First 1 + $Process = Get-CSProcess -Property Name -CimSession $TestCimSession1 | Select-Object -First 1 $Process | Should Not BeNullOrEmpty $Process.PSObject.TypeNames -contains $ProcessWMIType | Should Be $True $Process.VM | Should BeNullOrEmpty @@ -991,7 +993,7 @@ Describe 'Get-CSProcess' { Describe 'Get-CSEnvironmentVariable' { It 'should return a populated environment variable' { - $EnvVar = Get-CSEnvironmentVariable -NoProgressBar | Select-Object -First 1 + $EnvVar = Get-CSEnvironmentVariable | Select-Object -First 1 $EnvVar | Should Not BeNullOrEmpty $EnvVar.Name | Should Not BeNullOrEmpty $EnvVar.User | Should Not BeNullOrEmpty @@ -1000,7 +1002,7 @@ Describe 'Get-CSEnvironmentVariable' { } It 'should return a populated environment variable w/ CIM sessions' { - $EnvVar = Get-CSEnvironmentVariable -CimSession $TestCimSession1 -NoProgressBar | Select-Object -First 1 + $EnvVar = Get-CSEnvironmentVariable -CimSession $TestCimSession1 | Select-Object -First 1 $EnvVar | Should Not BeNullOrEmpty $EnvVar.Name | Should Not BeNullOrEmpty $EnvVar.User | Should Not BeNullOrEmpty @@ -1009,7 +1011,7 @@ Describe 'Get-CSEnvironmentVariable' { } It 'should return a populated system environment variable' { - $EnvVar = Get-CSEnvironmentVariable -SystemVariable -NoProgressBar | Select-Object -First 1 + $EnvVar = Get-CSEnvironmentVariable -SystemVariable | Select-Object -First 1 $EnvVar | Should Not BeNullOrEmpty $EnvVar.Name | Should Not BeNullOrEmpty $EnvVar.User | Should BeExactly '' @@ -1018,7 +1020,7 @@ Describe 'Get-CSEnvironmentVariable' { } It 'should return a populated system environment variable w/ CIM sessions' { - $EnvVar = Get-CSEnvironmentVariable -SystemVariable -CimSession $TestCimSession1 -NoProgressBar | Select-Object -First 1 + $EnvVar = Get-CSEnvironmentVariable -SystemVariable -CimSession $TestCimSession1 | Select-Object -First 1 $EnvVar | Should Not BeNullOrEmpty $EnvVar.Name | Should Not BeNullOrEmpty $EnvVar.User | Should BeExactly '' @@ -1027,7 +1029,7 @@ Describe 'Get-CSEnvironmentVariable' { } It 'should return a populated user environment variable' { - $EnvVar = Get-CSEnvironmentVariable -UserVariable -NoProgressBar | Select-Object -First 1 + $EnvVar = Get-CSEnvironmentVariable -UserVariable | Select-Object -First 1 $EnvVar | Should Not BeNullOrEmpty $EnvVar.Name | Should Not BeNullOrEmpty $EnvVar.User | Should Not BeNullOrEmpty @@ -1037,7 +1039,7 @@ Describe 'Get-CSEnvironmentVariable' { } It 'should return a populated user environment variable w/ CIM sessions' { - $EnvVar = Get-CSEnvironmentVariable -UserVariable -CimSession $TestCimSession1 -NoProgressBar | Select-Object -First 1 + $EnvVar = Get-CSEnvironmentVariable -UserVariable -CimSession $TestCimSession1 | Select-Object -First 1 $EnvVar | Should Not BeNullOrEmpty $EnvVar.Name | Should Not BeNullOrEmpty $EnvVar.User | Should Not BeNullOrEmpty @@ -1047,7 +1049,7 @@ Describe 'Get-CSEnvironmentVariable' { } It 'should return a named environment variable' { - $EnvVar = Get-CSEnvironmentVariable -VariableName TEMP -NoProgressBar | Select-Object -First 1 + $EnvVar = Get-CSEnvironmentVariable -VariableName TEMP | Select-Object -First 1 $EnvVar | Should Not BeNullOrEmpty $EnvVar.Name | Should BeExactly 'TEMP' $EnvVar.User | Should Not BeNullOrEmpty @@ -1056,7 +1058,7 @@ Describe 'Get-CSEnvironmentVariable' { } It 'should return a named environment variable w/ CIM sessions' { - $EnvVar = Get-CSEnvironmentVariable -VariableName TEMP -CimSession $TestCimSession1 -NoProgressBar | Select-Object -First 1 + $EnvVar = Get-CSEnvironmentVariable -VariableName TEMP -CimSession $TestCimSession1 | Select-Object -First 1 $EnvVar | Should Not BeNullOrEmpty $EnvVar.Name | Should BeExactly 'TEMP' $EnvVar.User | Should Not BeNullOrEmpty @@ -1065,7 +1067,7 @@ Describe 'Get-CSEnvironmentVariable' { } It 'should return a named system environment variable' { - $EnvVar = Get-CSEnvironmentVariable -SystemVariable -VariableName TEMP -NoProgressBar | Select-Object -First 1 + $EnvVar = Get-CSEnvironmentVariable -SystemVariable -VariableName TEMP | Select-Object -First 1 $EnvVar | Should Not BeNullOrEmpty $EnvVar.Name | Should BeExactly 'TEMP' $EnvVar.User | Should BeExactly '' @@ -1074,7 +1076,7 @@ Describe 'Get-CSEnvironmentVariable' { } It 'should return a named system environment variable w/ CIM sessions' { - $EnvVar = Get-CSEnvironmentVariable -SystemVariable -VariableName TEMP -CimSession $TestCimSession1 -NoProgressBar | Select-Object -First 1 + $EnvVar = Get-CSEnvironmentVariable -SystemVariable -VariableName TEMP -CimSession $TestCimSession1 | Select-Object -First 1 $EnvVar | Should Not BeNullOrEmpty $EnvVar.Name | Should BeExactly 'TEMP' $EnvVar.User | Should BeExactly '' @@ -1083,7 +1085,7 @@ Describe 'Get-CSEnvironmentVariable' { } It 'should return a named user environment variable' { - $EnvVar = Get-CSEnvironmentVariable -UserVariable -VariableName TEMP -NoProgressBar | Select-Object -First 1 + $EnvVar = Get-CSEnvironmentVariable -UserVariable -VariableName TEMP | Select-Object -First 1 $EnvVar | Should Not BeNullOrEmpty $EnvVar.Name | Should BeExactly 'TEMP' $EnvVar.User | Should Not BeNullOrEmpty @@ -1093,7 +1095,7 @@ Describe 'Get-CSEnvironmentVariable' { } It 'should return a named user environment variable w/ CIM sessions' { - $EnvVar = Get-CSEnvironmentVariable -UserVariable -VariableName TEMP -CimSession $TestCimSession1 -NoProgressBar | Select-Object -First 1 + $EnvVar = Get-CSEnvironmentVariable -UserVariable -VariableName TEMP -CimSession $TestCimSession1 | Select-Object -First 1 $EnvVar | Should Not BeNullOrEmpty $EnvVar.Name | Should BeExactly 'TEMP' $EnvVar.User | Should Not BeNullOrEmpty diff --git a/README.md b/README.md index 5ee0cb3..98ed5ea 100644 --- a/README.md +++ b/README.md @@ -104,7 +104,7 @@ All of the following requirements will have an accompanying Pester test to ensur #### Optional design considerations. 1. Your function should include a Pester test!!! How else can you be sure it works as designed and that it will be resiliant to refactoring? Without a Pester test, you'll just be left guessing as to whether or not your code will be stable in production. -2. All defensive or offensive functions should implement a -NoProgressBar parameter and to output a progress bar by default. A progress bar can come in very handy when running a sweep across 1000 systems. +2. All functions should utilize Write-Progress. A progress bar can come in very handy when running a sweep across 1000 systems. 3. All error or verbose messages should include the computer name for the local or remote session. This is helpful when diagnosing issues on a large number of remote sessions. #### Additional design considerations From b79a9518d705f89fa5c26ba79ccff81414bce229 Mon Sep 17 00:00:00 2001 From: Matt Graeber Date: Thu, 27 Oct 2016 13:08:56 -0700 Subject: [PATCH 02/15] Fixed a path used for a failing test --- CimSweep/Tests/Core.CimSweep.Tests.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CimSweep/Tests/Core.CimSweep.Tests.ps1 b/CimSweep/Tests/Core.CimSweep.Tests.ps1 index ddd0916..984d4c9 100644 --- a/CimSweep/Tests/Core.CimSweep.Tests.ps1 +++ b/CimSweep/Tests/Core.CimSweep.Tests.ps1 @@ -571,7 +571,7 @@ Describe 'Get-CSDirectoryListing' { } It 'should recurse one folder deep by piping output to itself' { - $ConfigDir = Get-CSDirectoryListing -DirectoryPath $SystemDirectory -Directory | Where-Object { $_.Name -eq "$SystemDirectory\config" } + $ConfigDir = Get-CSDirectoryListing -DirectoryPath $SystemDirectory -Directory | Where-Object { $_.Name -eq "$SystemDirectory\drivers" } $ConfigDirListing = $ConfigDir | Get-CSDirectoryListing | Select-Object -First 1 $ConfigDirListing | Should Not BeNullOrEmpty From 67d9e2936ac2671a4f7b9882fef2b051b4098088 Mon Sep 17 00:00:00 2001 From: Matt Graeber Date: Thu, 27 Oct 2016 13:09:15 -0700 Subject: [PATCH 03/15] Adding Get-CSInstalledAppCompatShimDatabase --- CimSweep/CimSweep.psd1 | 13 ++- CimSweep/Defense/AppCompatDatabases.ps1 | 139 ++++++++++++++++++++++++ 2 files changed, 150 insertions(+), 2 deletions(-) create mode 100644 CimSweep/Defense/AppCompatDatabases.ps1 diff --git a/CimSweep/CimSweep.psd1 b/CimSweep/CimSweep.psd1 index fcdb0d8..e2c4720 100644 --- a/CimSweep/CimSweep.psd1 +++ b/CimSweep/CimSweep.psd1 @@ -1,7 +1,7 @@ @{ RootModule = 'CimSweep.psm1' -ModuleVersion = '0.5.1.0' +ModuleVersion = '0.5.2.0' GUID = 'f347ef1c-d752-4d07-bf68-3197c0aa661a' @@ -35,7 +35,8 @@ FunctionsToExport = @( 'Get-CSWmiNamespace', 'Get-CSVulnerableServicePermission', 'Get-CSAVInfo', - 'Get-CSProxyConfig' + 'Get-CSProxyConfig', + 'Get-CSInstalledAppCompatShimDatabase' ) PrivateData = @{ @@ -48,6 +49,14 @@ PrivateData = @{ ProjectUri = 'https://github.com/PowerShellMafia/CimSweep' ReleaseNotes = @' +0.5.2 +----- +Enhancements: +* Added Get-CSInstalledAppCompatShimDatabase + +Removed: +* Removed the -NoProgressBar parameter from all functions since this is what $ProgressPreference is for. + 0.5.1 ----- Enhancements: diff --git a/CimSweep/Defense/AppCompatDatabases.ps1 b/CimSweep/Defense/AppCompatDatabases.ps1 new file mode 100644 index 0000000..2488933 --- /dev/null +++ b/CimSweep/Defense/AppCompatDatabases.ps1 @@ -0,0 +1,139 @@ +function Get-CSInstalledAppCompatShimDatabase { +<# +.SYNOPSIS + +List installed application compatibility databases. + +Author: Matthew Graeber (@mattifestation) +License: BSD 3-Clause + +.DESCRIPTION + +Get-InstalledAppCompatShimDatabase lists details about all installed application compatibility databases (SDB). While WMI is unable to parse installed SDBs, Get-InstalledAppCompatShimDatabase is useful for sweeping a large amount of systems for the purposes of identifying anomolous, installed databases. + +.PARAMETER CimSession + +Specifies the CIM session to use for this cmdlet. Enter a variable that contains the CIM session or a command that creates or gets the CIM session, such as the New-CimSession or Get-CimSession cmdlets. For more information, see about_CimSessions. + +.PARAMETER OperationTimeoutSec + +Specifies the amount of time that the cmdlet waits for a response from the computer. + +By default, the value of this parameter is 0, which means that the cmdlet uses the default timeout value for the server. + +If the OperationTimeoutSec parameter is set to a value less than the robust connection retry timeout of 3 minutes, network failures that last more than the value of the OperationTimeoutSec parameter are not recoverable, because the operation on the server times out before the client can reconnect. + +.EXAMPLE + +Get-CSRegistryAutoStart + +Lists all installed app compat databases. + +.OUTPUTS + +CimSweep.AppCompatDB + +Outputs objects representing the relevant information regarding installed application compatibility databases. Note: the InstallDateTime property is a UTC datet +#> + + [CmdletBinding()] + [OutputType('CimSweep.AppCompatDB')] + param( + [Alias('Session')] + [ValidateNotNullOrEmpty()] + [Microsoft.Management.Infrastructure.CimSession[]] + $CimSession, + + [UInt32] + [Alias('OT')] + $OperationTimeoutSec + ) + + BEGIN { + # If a CIM session is not provided, trick the function into thinking there is one. + if (-not $PSBoundParameters['CimSession']) { + $CimSession = '' + $CIMSessionCount = 1 + } else { + $CIMSessionCount = $CimSession.Count + } + + $CurrentCIMSession = 0 + + $Timeout = @{} + if ($PSBoundParameters['OperationTimeoutSec']) { $Timeout['OperationTimeoutSec'] = $OperationTimeoutSec } + } + + PROCESS { + foreach ($Session in $CimSession) { + $ComputerName = $Session.ComputerName + if (-not $Session.ComputerName) { $ComputerName = 'localhost' } + + # Display a progress activity for each CIM session + Write-Progress -Id 1 -Activity 'CimSweep - Installed App Compat database sweep' -Status "($($CurrentCIMSession+1)/$($CIMSessionCount)) Current computer: $ComputerName" -PercentComplete (($CurrentCIMSession / $CIMSessionCount) * 100) + $CurrentCIMSession++ + + $CommonArgs = @{} + + if ($Session.Id) { $CommonArgs['CimSession'] = $Session } + + # Collect all of the GUIDs for which each shimmed executable is associated. + $ShimmedExecutablesTable = Get-CSRegistryKey -Hive HKLM -SubKey 'SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Custom' @CommonArgs @Timeout | + Get-CSRegistryValue -ValueNameOnly | Group-Object -Property ValueName -AsHashTable + + $InstalledSdb = Get-CSRegistryKey -Hive HKLM -SubKey 'SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\InstalledSdb' @CommonArgs @Timeout + $CurrentSdb = 0 + + foreach ($Database in $InstalledSdb) { + $GUID = $Database.SubKey.Split('\')[-1] + + Write-Progress -Id 2 -ParentId 1 -Activity "Current database:" -Status "($($CurrentSdb+1)/$($InstalledSdb.Count)) $GUID" -PercentComplete (($CurrentSdb / $InstalledSdb.Count) * 100) + $CurrentSdb++ + + $DatabaseDetails = $Database | Get-CSRegistryValue | Group-Object -Property ValueName -AsHashTable + + $DatabasePath = $DatabaseDetails['DatabasePath'].ValueContent + $DatabasePathDir = Split-Path -Path $DatabasePath -Parent + $DatabasePathFileName = Split-Path -Path $DatabasePath -Leaf + $DatabaseFileInfo = Get-CSDirectoryListing -DirectoryPath $DatabasePathDir -FileName $DatabasePathFileName @CommonArgs @Timeout + + $ShimmedExecutables = $ShimmedExecutablesTable["$GUID.sdb"] | ForEach-Object { $_.Subkey.Split('\')[-1] } + + $IsPresentInAddRemovePrograms = $False + + $Result = Get-CSRegistryValue -Hive HKLM -SubKey "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$GUID.sdb" -ValueNameOnly @CommonArgs @Timeout + + if ($Result) { + $IsPresentInAddRemovePrograms = $True + } + + $ObjectProperties = [Ordered] @{ + PSTypeName = 'CimSweep.AppCompatDB' + DatabaseGUID = $GUID + DatabaseName = $DatabaseDetails['DatabaseDescription'].ValueContent + DatabasePath = $DatabasePath + DatabaseType = $DatabaseDetails['DatabaseType'].ValueContent + InstallDateTime = [DateTime]::FromFileTimeUtc($DatabaseDetails['DatabaseInstallTimeStamp'].ValueContent) + ShimmedExecutables = $ShimmedExecutables + IsPresentInAddRemovePrograms = $IsPresentInAddRemovePrograms + FileInfo = $DatabaseFileInfo + } + + $DefaultProperties = 'DatabaseGUID', 'DatabaseName', 'DatabasePath', 'DatabaseType', 'InstallDateTime', 'ShimmedExecutables', 'IsPresentInAddRemovePrograms', 'FileInfo' -as [Type] 'Collections.Generic.List[String]' + + if ($Database.PSComputerName) { + $ObjectProperties['PSComputerName'] = $_.PSComputerName + $DefaultProperties.Add('PSComputerName') + } else { + $ObjectProperties['PSComputerName'] = $null + } + + $InstalledDatabase = [PSCustomObject] $ObjectProperties + + Set-DefaultDisplayProperty -InputObject $InstalledDatabase -PropertyNames $DefaultProperties + + $InstalledDatabase + } + } + } +} \ No newline at end of file From fa4ab532cd1f5b61aa8c2cafcc6d82829a9d9815 Mon Sep 17 00:00:00 2001 From: Matt Graeber Date: Fri, 28 Oct 2016 13:41:51 -0700 Subject: [PATCH 04/15] Fixed typo in Get-CSInstalledAppCompatShimDatabase help --- CimSweep/Defense/AppCompatDatabases.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CimSweep/Defense/AppCompatDatabases.ps1 b/CimSweep/Defense/AppCompatDatabases.ps1 index 2488933..3501d35 100644 --- a/CimSweep/Defense/AppCompatDatabases.ps1 +++ b/CimSweep/Defense/AppCompatDatabases.ps1 @@ -33,7 +33,7 @@ Lists all installed app compat databases. CimSweep.AppCompatDB -Outputs objects representing the relevant information regarding installed application compatibility databases. Note: the InstallDateTime property is a UTC datet +Outputs objects representing the relevant information regarding installed application compatibility databases. Note: the InstallDateTime property is a UTC datetime. #> [CmdletBinding()] From 79458873140b98356bba5208a5ed6798d99d3705 Mon Sep 17 00:00:00 2001 From: Matt Graeber Date: Fri, 28 Oct 2016 13:43:57 -0700 Subject: [PATCH 05/15] Added Get-CSBitlockerKeyProtector Thanks @Invoke-IR for the requirements and motivation and thanks to Brian Reitz for originally discovering that this could be done with WMI. --- CimSweep/CimSweep.psd1 | 4 +- CimSweep/Defense/Bitlocker.ps1 | 292 +++++++++++++++++++++++++++++++++ 2 files changed, 295 insertions(+), 1 deletion(-) create mode 100644 CimSweep/Defense/Bitlocker.ps1 diff --git a/CimSweep/CimSweep.psd1 b/CimSweep/CimSweep.psd1 index e2c4720..ed7ec45 100644 --- a/CimSweep/CimSweep.psd1 +++ b/CimSweep/CimSweep.psd1 @@ -36,7 +36,8 @@ FunctionsToExport = @( 'Get-CSVulnerableServicePermission', 'Get-CSAVInfo', 'Get-CSProxyConfig', - 'Get-CSInstalledAppCompatShimDatabase' + 'Get-CSInstalledAppCompatShimDatabase', + 'Get-CSBitlockerKeyProtector' ) PrivateData = @{ @@ -53,6 +54,7 @@ PrivateData = @{ ----- Enhancements: * Added Get-CSInstalledAppCompatShimDatabase +* Added Get-CSBitlockerKeyProtector Removed: * Removed the -NoProgressBar parameter from all functions since this is what $ProgressPreference is for. diff --git a/CimSweep/Defense/Bitlocker.ps1 b/CimSweep/Defense/Bitlocker.ps1 new file mode 100644 index 0000000..192ba9d --- /dev/null +++ b/CimSweep/Defense/Bitlocker.ps1 @@ -0,0 +1,292 @@ +function Get-CSBitlockerKeyProtector { +<# +.SYNOPSIS + +Obtains Bitlocker volume key material. + +Author: Matthew Graeber (@mattifestation) +Inspiration/Motivation: Jared Atkinson (@jaredcatkinson), Brian Reitz +License: BSD 3-Clause + +.DESCRIPTION + +Get-CSBitlockerKeyProtector retrieves key material for BitLocker volumes. This function is used for the purposes of remotely decrypting and mounting Bitlocker volumes. Depending on the Bitlocker key protector used, Get-CSBitlockerKeyProtector will return any combination of the NumericalPassword, ExternalKey, KeyPackage, or Certificate. + +.PARAMETER DriveLetter + +Specifies the drive letter for the volume you want to obtain key Bitlocker key material from. If DriveLetter is not specified, key material for all encryptable volumes will be returned. + +.PARAMETER CimSession + +Specifies the CIM session to use for this cmdlet. Enter a variable that contains the CIM session or a command that creates or gets the CIM session, such as the New-CimSession or Get-CimSession cmdlets. For more information, see about_CimSessions. + +.PARAMETER OperationTimeoutSec + +Specifies the amount of time that the cmdlet waits for a response from the computer. + +By default, the value of this parameter is 0, which means that the cmdlet uses the default timeout value for the server. + +If the OperationTimeoutSec parameter is set to a value less than the robust connection retry timeout of 3 minutes, network failures that last more than the value of the OperationTimeoutSec parameter are not recoverable, because the operation on the server times out before the client can reconnect. + +.EXAMPLE + +Get-CSBitlockerKeyProtector + +List all recoverable Bitlocker key material for each encryptable volume. + +.EXAMPLE + +Get-CSBitlockerKeyProtector -DriveLetter C: + +List all recoverable Bitlocker key material for the C: volume. + +.OUTPUTS + +CimSweep.BitlockerKeyProtector + +Outputs objects representing Bitlocker volume key material. +#> + + [CmdletBinding()] + [OutputType('CimSweep.BitlockerKeyProtector')] + param( + [ValidatePattern('^[A-Z]:?$')] + [String] + $DriveLetter, + + [Alias('Session')] + [ValidateNotNullOrEmpty()] + [Microsoft.Management.Infrastructure.CimSession[]] + $CimSession, + + [UInt32] + [Alias('OT')] + $OperationTimeoutSec + ) + + BEGIN { + # If a CIM session is not provided, trick the function into thinking there is one. + if (-not $PSBoundParameters['CimSession']) { + $CimSession = '' + $CIMSessionCount = 1 + } else { + $CIMSessionCount = $CimSession.Count + } + + $CurrentCIMSession = 0 + + $KeyProtectorTypes = @{ + 0 = 'Unknown or other protector type' + 1 = 'Trusted Platform Module (TPM)' + 2 = 'External key' + 3 = 'Numerical password' + 4 = 'TPM And PIN' + 5 = 'TPM And Startup Key' + 6 = 'TPM And PIN And Startup Key' + 7 = 'Public Key' + 8 = 'Passphrase' + 9 = 'TPM Certificate' + 10 = 'CryptoAPI Next Generation (CNG) Protector' + } + } + + PROCESS { + foreach ($Session in $CimSession) { + $ComputerName = $Session.ComputerName + if (-not $Session.ComputerName) { $ComputerName = 'localhost' } + + # Display a progress activity for each CIM session + Write-Progress -Id 1 -Activity 'CimSweep - Bitlocker key protector sweep' -Status "($($CurrentCIMSession+1)/$($CIMSessionCount)) Current computer: $ComputerName" -PercentComplete (($CurrentCIMSession / $CIMSessionCount) * 100) + $CurrentCIMSession++ + + $CommonArgs = @{} + if ($Session.Id) { $CommonArgs['CimSession'] = $Session } + if ($OperationTimeoutSec) { $CommonArgs['OperationTimeoutSec'] = $OperationTimeoutSec } + + $VolumeArgs = @{ + Namespace = 'root/cimv2/security/microsoftvolumeencryption' + ClassName = 'Win32_EncryptableVolume' + Property = 'ProtectionStatus', 'DriveLetter', 'DeviceID' + } + + if ($DriveLetter) { $VolumeArgs['Filter'] = "DriveLetter='$($DriveLetter[0]):'" } + + $Volumes = @(Get-CimInstance @CommonArgs @VolumeArgs) + + $VolCount = 0 + + foreach ($CurrentVolume in $Volumes) { + Write-Progress -Id 2 -ParentId 1 -Activity "Current volume:" -Status "($($VolCount+1)/$($Volumes.Count)) $($CurrentVolume.DriveLetter)" -PercentComplete (($VolCount / $Volumes.Count) * 100) + $VolCount++ + + if ($CurrentVolume.ProtectionStatus -ne 1) { + Write-Warning "[$ComputerName] Drive letter $($CurrentVolume.DriveLetter) is not Bitlocker protected." + continue + } + + $Result = Invoke-CimMethod -CimInstance $CurrentVolume -MethodName GetKeyProtectors @CommonArgs + + if ($Result.ReturnValue) { + Write-Error "[$ComputerName] Unable to obtain key protectors from drive letter: $($CurrentVolume.DriveLetter)" + continue + } + + $ProtectorCount = 0 + $KeyProtectorIDs = @($Result.VolumeKeyProtectorID) + + foreach ($ProtectorID in $KeyProtectorIDs) { + Write-Progress -Id 3 -ParentId 2 -Activity "Current key protector ID:" -Status "($($ProtectorCount+1)/$($KeyProtectorIDs.Count)) $ProtectorID" -PercentComplete (($ProtectorCount / $KeyProtectorIDs.Count) * 100) + $ProtectorCount++ + + $MethodArgs = @{ + CimInstance = $CurrentVolume + Arguments = @{ VolumeKeyProtectorID = $ProtectorID } + } + + $Result = Invoke-CimMethod -MethodName GetKeyProtectorType @CommonArgs @MethodArgs + + if ($Result.ReturnValue) { + Write-Error "[$ComputerName] Unable to obtain key protector type for drive letter: $($CurrentVolume.DriveLetter), VolumeKeyProtectorID: $ProtectorID" + continue + } + + $KeyProtectorFriendlyName = $KeyProtectorTypes[[Int] $Result.KeyProtectorType] + + $ExternalKeyFileName = $null + $ExternalKeyBytes = $null + $NumericalPassword = $null + $KeyPackage = $null + $KeyProtectorCertificate = $null + + $ErrorTemplate = "for drive letter: $($CurrentVolume.DriveLetter), VolumeKeyProtectorID: $ProtectorID" + + switch ($KeyProtectorFriendlyName) { + 'External key' { + $Result = Invoke-CimMethod -MethodName GetExternalKeyFileName @CommonArgs @MethodArgs + + if ($Result.ReturnValue) { + Write-Error "[$ComputerName] Unable to obtain external key file name $ErrorTemplate" + continue + } + + $ExternalKeyFileName = $Result.FileName + + $Result = Invoke-CimMethod -MethodName GetKeyProtectorExternalKey @CommonArgs @MethodArgs + + if ($Result.ReturnValue) { + Write-Error "[$ComputerName] Unable to obtain external key bytes $ErrorTemplate" + continue + } + + $ExternalKeyBytes = $Result.ExternalKey + + $Result = Invoke-CimMethod -MethodName GetKeyPackage @CommonArgs @MethodArgs + + if ($Result.ReturnValue) { + Write-Error "[$ComputerName] Unable to obtain key package $ErrorTemplate" + continue + } + + $KeyPackage = $Result.KeyPackage + } + + 'Numerical password' { + $Result = Invoke-CimMethod -MethodName GetKeyProtectorNumericalPassword @CommonArgs @MethodArgs + + if ($Result.ReturnValue) { + Write-Error "[$ComputerName] Unable to obtain numerical password $ErrorTemplate" + continue + } + + $NumericalPassword = $Result.NumericalPassword + + $Result = Invoke-CimMethod -MethodName GetKeyPackage @CommonArgs @MethodArgs + + if ($Result.ReturnValue) { + Write-Error "[$ComputerName] Unable to obtain key package $ErrorTemplate" + continue + } + + $KeyPackage = $Result.KeyPackage + } + + 'TPM And Startup Key' { + $Result = Invoke-CimMethod -MethodName GetExternalKeyFileName @CommonArgs @MethodArgs + + if ($Result.ReturnValue) { + Write-Error "[$ComputerName] Unable to obtain external key file name $ErrorTemplate" + continue + } + + $ExternalKeyFileName = $Result.FileName + + $Result = Invoke-CimMethod -MethodName GetKeyProtectorExternalKey @CommonArgs @MethodArgs + + if ($Result.ReturnValue) { + Write-Error "[$ComputerName] Unable to obtain external key bytes $ErrorTemplate" + continue + } + + $ExternalKeyBytes = $Result.ExternalKey + } + + 'TPM And PIN And Startup Key' { + $Result = Invoke-CimMethod -MethodName GetExternalKeyFileName @CommonArgs @MethodArgs + + if ($Result.ReturnValue) { + Write-Error "[$ComputerName] Unable to obtain external key file name $ErrorTemplate" + continue + } + + $ExternalKeyFileName = $Result.FileName + + $Result = Invoke-CimMethod -MethodName GetKeyProtectorExternalKey @CommonArgs @MethodArgs + + if ($Result.ReturnValue) { + Write-Error "[$ComputerName] Unable to obtain external key bytes $ErrorTemplate" + continue + } + + $ExternalKeyBytes = $Result.ExternalKey + } + + 'Public Key' { + $Result = Invoke-CimMethod -CimInstance $CurrentVolume -MethodName GetKeyProtectorCertificate -Arguments @{ VolumeKeyProtectorID = $ProtectorID } @CommonArgs + + if ($Result.ReturnValue) { + Write-Error "[$ComputerName] Unable to obtain protector certificate $ErrorTemplate" + continue + } + + $KeyProtectorCertificate = [PSCustomObject] @{ + PSTypeName = 'CimSweep.KeyProtector.BitlockerKeyProtector' + PublicKey = $Result.PublicKey + CertThumbprint = $Result.CertThumbprint + CertType = if ($Result.CertType -eq 1) { 'DataRecoveryAgent' } else { 'UserCertificate' } + } + } + } + + $ProtectorProperties = [Ordered] @{ + PSTypeName = 'CimSweep.BitlockerKeyProtector' + DriveLetter = $CurrentVolume.DriveLetter + DeviceID = $CurrentVolume.DeviceID + KeyProtectorID = $ProtectorID + KeyProtectorFriendlyName = $KeyProtectorFriendlyName + NumericalPassword = $NumericalPassword + ExternalKeyFileName = $ExternalKeyFileName + ExternalKeyBytes = $ExternalKeyBytes + KeyPackage = $KeyPackage + Certificate = $KeyProtectorCertificate + } + + if ($CurrentVolume.PSComputerName) { + $ProtectorProperties['PSComputerName'] = $CurrentVolume.PSComputerName + } + + [PSCustomObject] $ProtectorProperties + } + } + } + } +} \ No newline at end of file From 1ec0b4ed9b6dc9305957260fcb81c6bd4bbd6fb1 Mon Sep 17 00:00:00 2001 From: Matt Graeber Date: Fri, 28 Oct 2016 16:12:51 -0700 Subject: [PATCH 06/15] Removing Set-DefaultDisplayProperty helper function This was creating an unnecessary amount of boilerplate code for all functions. --- CimSweep/CimSweep.psm1 | 26 ---- CimSweep/Core/CoreFunctions.ps1 | 183 ++++-------------------- CimSweep/Defense/AppCompatDatabases.ps1 | 11 +- CimSweep/Defense/Autoruns.ps1 | 24 +--- CimSweep/Defense/Bitlocker.ps1 | 6 +- CimSweep/Offense/ACLAudits.ps1 | 7 +- CimSweep/Offense/AntiVirusInfo.ps1 | 25 ++-- CimSweep/Offense/ProxyConfig.ps1 | 7 +- CimSweep/Tests/Core.CimSweep.Tests.ps1 | 33 ----- 9 files changed, 61 insertions(+), 261 deletions(-) diff --git a/CimSweep/CimSweep.psm1 b/CimSweep/CimSweep.psm1 index f09b798..6f279b2 100644 --- a/CimSweep/CimSweep.psm1 +++ b/CimSweep/CimSweep.psm1 @@ -3,32 +3,6 @@ Get-ChildItem -Include '*.ps1' | ForEach-Object { . $_.FullName } -<# -Helper function used to explicitly set which object properties are displayed -This is used primarily to hide CimSession properties and to display PSComputerName -only if a function was performed against a remote computer. - -Technique described here: https://poshoholic.com/2008/07/05/essential-powershell-define-default-properties-for-custom-objects/ -Thanks Kirk Munro (@Poshoholic)! - -Ignore PsScriptAnalyzer rule for this verb name. It is a helper function that doesn't modify system state. -#> -function Set-DefaultDisplayProperty { - [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')] - Param ( - [Parameter(Mandatory = $True, ValueFromPipeline = $True)] - [Object] - $InputObject, - - [Parameter(Mandatory = $True)] - [String[]] - $PropertyNames - ) - - $DefaultDisplayPropertySet = New-Object Management.Automation.PSPropertySet(‘DefaultDisplayPropertySet’, [String[]] $PropertyNames) - $PSStandardMembers = [Management.Automation.PSMemberInfo[]]@($DefaultDisplayPropertySet) - Add-Member -InputObject $InputObject -MemberType MemberSet -Name PSStandardMembers -Value $PSStandardMembers -} function Get-HKUSID { <# diff --git a/CimSweep/Core/CoreFunctions.ps1 b/CimSweep/Core/CoreFunctions.ps1 index ee39747..5046af8 100644 --- a/CimSweep/Core/CoreFunctions.ps1 +++ b/CimSweep/Core/CoreFunctions.ps1 @@ -164,8 +164,6 @@ It is not recommended to recursively list all registry keys from most parent key SubKey = $NewSubKey } - $DefaultProperties = @('Hive', 'SubKey') -as [Type] 'Collections.Generic.List[String]' - if ($IncludeAcl) { $GetSDArgs = @{ Namespace = 'root/default' @@ -207,20 +205,10 @@ It is not recommended to recursively list all registry keys from most parent key $ObjectProperties['ACL'] = $RegSD } - if ($Result.PSComputerName) { - $ObjectProperties['PSComputerName'] = $Result.PSComputerName - $DefaultProperties.Add('PSComputerName') - } else { - $ObjectProperties['PSComputerName'] = $null - } - + if ($Result.PSComputerName) { $ObjectProperties['PSComputerName'] = $Result.PSComputerName } if ($Session.Id) { $ObjectProperties['CimSession'] = $Session } - $KeyObject = New-Object -TypeName PSObject -Property $ObjectProperties - - Set-DefaultDisplayProperty -InputObject $KeyObject -PropertyNames $DefaultProperties - - $KeyObject + [PSCustomObject] $ObjectProperties if ($PSBoundParameters['Recurse']) { $ObjectProperties.Remove('PSTypeName') @@ -485,6 +473,7 @@ Outputs a list of objects representing registry value names, their respective ty } $ObjectProperties = [Ordered] @{ + PSTypeName = 'CimSweep.RegistryValue' Hive = $Hive SubKey = $TrimmedKey ValueName = if ($ValueName) { $ValueName } else { '(Default)' } @@ -492,23 +481,10 @@ Outputs a list of objects representing registry value names, their respective ty ValueContent = $ValueContent } - $DefaultProperties = [String[]] $ObjectProperties.Keys -as [Type] 'Collections.Generic.List[String]' - $ObjectProperties['PSTypeName'] = 'CimSweep.RegistryValue' - - if ($Result.PSComputerName) { - $ObjectProperties['PSComputerName'] = $Result.PSComputerName - $DefaultProperties.Add('PSComputerName') - } else { - $ObjectProperties['PSComputerName'] = $null - } - + if ($Result.PSComputerName) { $ObjectProperties['PSComputerName'] = $Result.PSComputerName } if ($Session.Id) { $ObjectProperties['CimSession'] = $Session } - $ValueObject = [PSCustomObject] $ObjectProperties - - Set-DefaultDisplayProperty -InputObject $ValueObject -PropertyNames $DefaultProperties - - $ValueObject + [PSCustomObject] $ObjectProperties } else { $CimMethodArgs['MethodName'] = 'EnumValues' @@ -616,6 +592,7 @@ Outputs a list of objects representing registry value names, their respective ty } $ObjectProperties = [Ordered] @{ + PSTypeName = 'CimSweep.RegistryValue' Hive = $Hive SubKey = $TrimmedKey ValueName = if ($ValueNames[$i]) { $ValueNames[$i] } else { '(Default)' } @@ -623,23 +600,10 @@ Outputs a list of objects representing registry value names, their respective ty ValueContent = $ValueContent } - $DefaultProperties = [String[]] $ObjectProperties.Keys -as [Type] 'Collections.Generic.List[String]' - $ObjectProperties['PSTypeName'] = 'CimSweep.RegistryValue' - - if ($Result.PSComputerName) { - $ObjectProperties['PSComputerName'] = $Result.PSComputerName - $DefaultProperties.Add('PSComputerName') - } else { - $ObjectProperties['PSComputerName'] = $null - } - + if ($Result.PSComputerName) { $ObjectProperties['PSComputerName'] = $Result.PSComputerName } if ($Session.Id) { $ObjectProperties['CimSession'] = $Session } - $ValueObject = [PSCustomObject] $ObjectProperties - - Set-DefaultDisplayProperty -InputObject $ValueObject -PropertyNames $DefaultProperties - - $ValueObject + [PSCustomObject] $ObjectProperties } } } @@ -743,22 +707,10 @@ Outputs objects representing the available event logs which can be piped to Get- LogName = $_.LogfileName } - $DefaultProperties = @('LogName') -as [Type] 'Collections.Generic.List[String]' - - if ($_.PSComputerName) { - $ObjectProperties['PSComputerName'] = $_.PSComputerName - $DefaultProperties.Add('PSComputerName') - } else { - $ObjectProperties['PSComputerName'] = $null - } - + if ($_.PSComputerName) { $ObjectProperties['PSComputerName'] = $_.PSComputerName } if ($Session.Id) { $ObjectProperties['CimSession'] = $Session } - $EventLog = [PSCustomObject] $ObjectProperties - - Set-DefaultDisplayProperty -InputObject $EventLog -PropertyNames $DefaultProperties - - $EventLog + [PSCustomObject] $ObjectProperties } } } @@ -1117,22 +1069,10 @@ Outputs a list of mounted drive letters. DirectoryPath = "$($Volume.DeviceID)\" } - $DefaultProperties = 'DriveLetter', 'DirectoryPath' -as [Type] 'Collections.Generic.List[String]' - - if ($Volume.PSComputerName) { - $ObjectProperties['PSComputerName'] = $Volume.PSComputerName - $DefaultProperties.Add('PSComputerName') - } else { - $ObjectProperties['PSComputerName'] = $null - } - + if ($Volume.PSComputerName) { $ObjectProperties['PSComputerName'] = $Volume.PSComputerName } if ($Session.Id) { $ObjectProperties['CimSession'] = $Session } - $DiskInfo = [PSCustomObject] $ObjectProperties - - Set-DefaultDisplayProperty -InputObject $DiskInfo -PropertyNames $DefaultProperties - - $DiskInfo + [PSCustomObject] $ObjectProperties } } } @@ -2416,7 +2356,6 @@ Outputs objects consisting of the name, value, and scope (user vs. system) of an $SystemEnvPath = 'SYSTEM\CurrentControlSet\Control\Session Manager\Environment' $ObjectType = 'CimSweep.EnvironmentVariable' - $DefaultPropertyNames = 'Name', 'User', 'VariableValue' } PROCESS { @@ -2445,22 +2384,10 @@ Outputs objects consisting of the name, value, and scope (user vs. system) of an VariableValue = $Result.ValueContent } - $DefaultProperties = $DefaultPropertyNames -as [Type] 'Collections.Generic.List[String]' - - if ($Result.PSComputerName) { - $ObjectProperties['PSComputerName'] = $Result.PSComputerName - $DefaultProperties.Add('PSComputerName') - } else { - $ObjectProperties['PSComputerName'] = $null - } - + if ($Result.PSComputerName) { $ObjectProperties['PSComputerName'] = $Result.PSComputerName} if ($Session.Id) { $ObjectProperties['CimSession'] = $Session } - $EnvVarInfo = [PSCustomObject] $ObjectProperties - - Set-DefaultDisplayProperty -InputObject $EnvVarInfo -PropertyNames $DefaultProperties - - $EnvVarInfo + [PSCustomObject] $ObjectProperties } } @@ -2480,22 +2407,11 @@ Outputs objects consisting of the name, value, and scope (user vs. system) of an VariableValue = $Result.ValueContent } - $DefaultProperties = $DefaultPropertyNames -as [Type] 'Collections.Generic.List[String]' - - if ($Result.PSComputerName) { - $ObjectProperties['PSComputerName'] = $Result.PSComputerName - $DefaultProperties.Add('PSComputerName') - } else { - $ObjectProperties['PSComputerName'] = $null - } + if ($Result.PSComputerName) { $ObjectProperties['PSComputerName'] = $Result.PSComputerName } if ($Session.Id) { $ObjectProperties['CimSession'] = $Session } - $EnvVarInfo = [PSCustomObject] $ObjectProperties - - Set-DefaultDisplayProperty -InputObject $EnvVarInfo -PropertyNames $DefaultProperties - - $EnvVarInfo + [PSCustomObject] $ObjectProperties } else { $Result = Get-CSRegistryValue -Hive HKU -SubKey "$SID\Environment" -ValueName $VariableName -ValueType REG_SZ @CommonArgs @Timeout @@ -2507,22 +2423,10 @@ Outputs objects consisting of the name, value, and scope (user vs. system) of an VariableValue = $Result.ValueContent } - $DefaultProperties = $DefaultPropertyNames -as [Type] 'Collections.Generic.List[String]' - - if ($Result.PSComputerName) { - $ObjectProperties['PSComputerName'] = $Result.PSComputerName - $DefaultProperties.Add('PSComputerName') - } else { - $ObjectProperties['PSComputerName'] = $null - } - + if ($Result.PSComputerName) { $ObjectProperties['PSComputerName'] = $Result.PSComputerName } if ($Session.Id) { $ObjectProperties['CimSession'] = $Session } - $EnvVarInfo = [PSCustomObject] $ObjectProperties - - Set-DefaultDisplayProperty -InputObject $EnvVarInfo -PropertyNames $DefaultProperties - - $EnvVarInfo + [PSCustomObject] $ObjectProperties } } } @@ -2537,22 +2441,10 @@ Outputs objects consisting of the name, value, and scope (user vs. system) of an VariableValue = $_.ValueContent } - $DefaultProperties = $DefaultPropertyNames -as [Type] 'Collections.Generic.List[String]' - - if ($_.PSComputerName) { - $ObjectProperties['PSComputerName'] = $_.PSComputerName - $DefaultProperties.Add('PSComputerName') - } else { - $ObjectProperties['PSComputerName'] = $null - } - + if ($_.PSComputerName) { $ObjectProperties['PSComputerName'] = $_.PSComputerName } if ($Session.Id) { $ObjectProperties['CimSession'] = $Session } - $EnvVarInfo = [PSCustomObject] $ObjectProperties - - Set-DefaultDisplayProperty -InputObject $EnvVarInfo -PropertyNames $DefaultProperties - - $EnvVarInfo + [PSCustomObject] $ObjectProperties } } @@ -2570,22 +2462,10 @@ Outputs objects consisting of the name, value, and scope (user vs. system) of an VariableValue = $_.ValueContent } - $DefaultProperties = $DefaultPropertyNames -as [Type] 'Collections.Generic.List[String]' - - if ($_.PSComputerName) { - $ObjectProperties['PSComputerName'] = $_.PSComputerName - $DefaultProperties.Add('PSComputerName') - } else { - $ObjectProperties['PSComputerName'] = $null - } - + if ($_.PSComputerName) { $ObjectProperties['PSComputerName'] = $_.PSComputerName } if ($Session.Id) { $ObjectProperties['CimSession'] = $Session } - $EnvVarInfo = [PSCustomObject] $ObjectProperties - - Set-DefaultDisplayProperty -InputObject $EnvVarInfo -PropertyNames $DefaultProperties - - $EnvVarInfo + [PSCustomObject] $ObjectProperties } Get-CSRegistryValue -Hive HKU -SubKey "$SID\Environment" @CommonArgs @Timeout | ForEach-Object { @@ -2596,22 +2476,10 @@ Outputs objects consisting of the name, value, and scope (user vs. system) of an VariableValue = $_.ValueContent } - $DefaultProperties = $DefaultPropertyNames -as [Type] 'Collections.Generic.List[String]' - - if ($_.PSComputerName) { - $ObjectProperties['PSComputerName'] = $_.PSComputerName - $DefaultProperties.Add('PSComputerName') - } else { - $ObjectProperties['PSComputerName'] = $null - } - + if ($_.PSComputerName) { $ObjectProperties['PSComputerName'] = $_.PSComputerName } if ($Session.Id) { $ObjectProperties['CimSession'] = $Session } - $EnvVarInfo = [PSCustomObject] $ObjectProperties - - Set-DefaultDisplayProperty -InputObject $EnvVarInfo -PropertyNames $DefaultProperties - - $EnvVarInfo + [PSCustomObject] $ObjectProperties } } } @@ -2789,8 +2657,6 @@ Microsoft.Management.Infrastructure.CimInstance#root/__NAMESPACE $ComputerName = $Session.ComputerName if (-not $Session.ComputerName) { $ComputerName = 'localhost' } - $DefaultProperties = 'FullyQualifiedNamespace' -as [Type] 'Collections.Generic.List[String]' - $CommonArgs = @{} if ($Session.Id) { $CommonArgs['CimSession'] = $Session } @@ -2835,7 +2701,6 @@ Microsoft.Management.Infrastructure.CimInstance#root/__NAMESPACE } Add-Member -InputObject $_ -NotePropertyName FullyQualifiedNamespace -NotePropertyValue $FullyQualifiedNamespace - Set-DefaultDisplayProperty -InputObject $_ -PropertyNames $DefaultProperties $_ diff --git a/CimSweep/Defense/AppCompatDatabases.ps1 b/CimSweep/Defense/AppCompatDatabases.ps1 index 3501d35..047ef61 100644 --- a/CimSweep/Defense/AppCompatDatabases.ps1 +++ b/CimSweep/Defense/AppCompatDatabases.ps1 @@ -119,20 +119,11 @@ Outputs objects representing the relevant information regarding installed applic FileInfo = $DatabaseFileInfo } - $DefaultProperties = 'DatabaseGUID', 'DatabaseName', 'DatabasePath', 'DatabaseType', 'InstallDateTime', 'ShimmedExecutables', 'IsPresentInAddRemovePrograms', 'FileInfo' -as [Type] 'Collections.Generic.List[String]' - if ($Database.PSComputerName) { $ObjectProperties['PSComputerName'] = $_.PSComputerName - $DefaultProperties.Add('PSComputerName') - } else { - $ObjectProperties['PSComputerName'] = $null } - $InstalledDatabase = [PSCustomObject] $ObjectProperties - - Set-DefaultDisplayProperty -InputObject $InstalledDatabase -PropertyNames $DefaultProperties - - $InstalledDatabase + [PSCustomObject] $ObjectProperties } } } diff --git a/CimSweep/Defense/Autoruns.ps1 b/CimSweep/Defense/Autoruns.ps1 index c5a1a35..9143595 100644 --- a/CimSweep/Defense/Autoruns.ps1 +++ b/CimSweep/Defense/Autoruns.ps1 @@ -202,22 +202,9 @@ Outputs objects representing autoruns entries similar to the output of Sysintern Category = $Category } - $DefaultProperties = 'Path', 'AutoRunEntry', 'ImagePath', 'Category' -as [Type] 'Collections.Generic.List[String]' + if ($PSComputerName) { $ObjectProperties['PSComputerName'] = $PSComputerName } - if ($PSComputerName) { - $ObjectProperties['PSComputerName'] = $PSComputerName - $DefaultProperties.Add('PSComputerName') - } else { - $ObjectProperties['PSComputerName'] = $null - } - - if ($Session.Id) { $ObjectProperties['CimSession'] = $Session } - - $AutoRunsEntry = [PSCustomObject] $ObjectProperties - - Set-DefaultDisplayProperty -InputObject $AutoRunsEntry -PropertyNames $DefaultProperties - - $AutoRunsEntry + [PSCustomObject] $ObjectProperties } } @@ -715,14 +702,17 @@ Get-CSWmiPersistence only returns output when __FilterToConsumerBinding instance Write-Verbose "[$($Session.ComputerName)] Correlating referenced __EventConsumer instance." $Consumer = Get-CimInstance -Namespace root/subscription -ClassName $ConsumerClass -Filter "Name=`"$($_.Consumer.Name)`"" @CommonArgs @Timeout - [PSCustomObject] @{ + $ObjectProperties = [Ordered] @{ PSTypeName = 'CimSweep.WmiPersistence' Filter = $Filter ConsumerClass = $ConsumerClass Consumer = $Consumer FilterToConsumerBinding = $_ - PSComputerName = $_.PSComputerName } + + if ($_.PSComputerName) { $ObjectProperties['PSComputerName'] = $_.PSComputerName } + + [PSCustomObject] $ObjectProperties } } } diff --git a/CimSweep/Defense/Bitlocker.ps1 b/CimSweep/Defense/Bitlocker.ps1 index 192ba9d..9bffa26 100644 --- a/CimSweep/Defense/Bitlocker.ps1 +++ b/CimSweep/Defense/Bitlocker.ps1 @@ -5,7 +5,7 @@ Obtains Bitlocker volume key material. Author: Matthew Graeber (@mattifestation) -Inspiration/Motivation: Jared Atkinson (@jaredcatkinson), Brian Reitz +Inspiration/Motivation: Jared Atkinson (@jaredcatkinson), Brian Reitz (@brian_psu) License: BSD 3-Clause .DESCRIPTION @@ -280,9 +280,7 @@ Outputs objects representing Bitlocker volume key material. Certificate = $KeyProtectorCertificate } - if ($CurrentVolume.PSComputerName) { - $ProtectorProperties['PSComputerName'] = $CurrentVolume.PSComputerName - } + if ($CurrentVolume.PSComputerName) { $ProtectorProperties['PSComputerName'] = $CurrentVolume.PSComputerName } [PSCustomObject] $ProtectorProperties } diff --git a/CimSweep/Offense/ACLAudits.ps1 b/CimSweep/Offense/ACLAudits.ps1 index 4b462cb..a960da4 100644 --- a/CimSweep/Offense/ACLAudits.ps1 +++ b/CimSweep/Offense/ACLAudits.ps1 @@ -199,7 +199,7 @@ Service ACL sweep across a large amount of hosts will take a long time. foreach ($Group in $UserGrouping.Keys) { $Permissions = $UserGrouping[$Group] - [PSCustomObject] @{ + $ObjectProperties = [Ordered] @{ PSTypeName = 'CimSweep.ServiceACLAudit' GroupName = $Group CanStartService = $Permissions.ServiceCanStart @@ -213,8 +213,11 @@ Service ACL sweep across a large amount of hosts will take a long time. CanWriteToFile = $Permissions.FileCanWrite CanWriteDataToFile = $Permissions.FileCanWriteData FullControlOfFile = $Permissions.FileHasFullControl - PSComputerName = $Session.ComputerName } + + if ($Session.ComputerName) { $ObjectProperties['PSComputerName'] = $Session.ComputerName } + + [PSCustomObject] $ObjectProperties } } } diff --git a/CimSweep/Offense/AntiVirusInfo.ps1 b/CimSweep/Offense/AntiVirusInfo.ps1 index 5d65621..0255fd7 100644 --- a/CimSweep/Offense/AntiVirusInfo.ps1 +++ b/CimSweep/Offense/AntiVirusInfo.ps1 @@ -93,7 +93,7 @@ Outputs custom objects representing the current AV configuration. if ($InstanceArgs['NameSpace'] -eq 'root/SecurityCenter2') { - $AntiVirus = [PSCustomObject] @{ + $ObjectProperties = [Ordered] @{ PSTypeName = 'CimSweep.AVInfo' Name = $AV.displayName Executable = $AV.pathToSignedProductExe @@ -101,7 +101,6 @@ Outputs custom objects representing the current AV configuration. ScannerEnabled = $null Updated = $null ExclusionInfo = $null - PSComputerName = $Session.ComputerName } #parse the byte value of productstate @@ -111,26 +110,31 @@ Outputs custom objects representing the current AV configuration. if($scanner -ge (10 -as [byte])) { - $AntiVirus.ScannerEnabled = $True + $ObjectProperties.ScannerEnabled = $True } elseif($scanner -eq (00 -as [byte]) -or $scanner -eq (01 -as [byte])) { - $AntiVirus.ScannerEnabled = $False + $ObjectProperties.ScannerEnabled = $False } #Determine if the AV definitions are up to date if($updated -eq (00 -as [byte])) { - $AntiVirus.Updated = $True + $ObjectProperties.Updated = $True } elseif($updated -eq (10 -as [byte])) { - $AntiVirus.Updated = $False - } + $ObjectProperties.Updated = $False + } + + if ($Session.ComputerName) { $ObjectProperties['PSComputerName'] = $Session.ComputerName } + + $AntiVirus = [PSCustomObject] $ObjectProperties } else { - $AntiVirus = [PSCustomObject] @{ + $ObjectProperties = [Ordered] @{ + PSTypeName = 'CimSweep.AVInfo' Name = $AV.displayName Executable = $AV.pathToEnableOnAccessUI InstanceGUID = $AV.instanceGuid @@ -139,6 +143,10 @@ Outputs custom objects representing the current AV configuration. ExclusionInfo = $null PSComputerName = $Session.ComputerName } + + if ($Session.ComputerName) { $ObjectProperties['PSComputerName'] = $Session.ComputerName } + + $AntiVirus = [PSCustomObject] $ObjectProperties } @@ -172,6 +180,7 @@ Outputs custom objects representing the current AV configuration. } $AntiVirus.ExclusionInfo = $ExclusionInfo + $AntiVirus } } diff --git a/CimSweep/Offense/ProxyConfig.ps1 b/CimSweep/Offense/ProxyConfig.ps1 index f68ca24..7271ece 100644 --- a/CimSweep/Offense/ProxyConfig.ps1 +++ b/CimSweep/Offense/ProxyConfig.ps1 @@ -102,13 +102,16 @@ CimSweep.ProxyConfig #If the 5th byte is even, the AutoDetectProxySetting is most likely enabled if (($ProxyConfig.ValueContent[4] % 2) -eq 0) { $AutoDetectProxy = $True } - $ProxySettings = [PSCustomObject] @{ + $ObjectProperties = [Ordered] @{ PSTypeName = 'CimSweep.ProxyConfig' AutoDetectProxy = $AutoDetectProxy InternetSettings = $null - PSComputerName = $Session.ComputerName } + if ($Session.ComputerName) { $ObjectProperties['PSComputerName'] = $Session.ComputerName } + + $ProxySettings = [PSCustomObject] $ObjectProperties + #Get the current Internet Settings from the registry $SubKey = $SubKey.TrimEnd('Connections') $InternetSettings = [PSCustomObject] @{} diff --git a/CimSweep/Tests/Core.CimSweep.Tests.ps1 b/CimSweep/Tests/Core.CimSweep.Tests.ps1 index 984d4c9..4b9c77c 100644 --- a/CimSweep/Tests/Core.CimSweep.Tests.ps1 +++ b/CimSweep/Tests/Core.CimSweep.Tests.ps1 @@ -104,12 +104,6 @@ Describe 'Get-CSRegistryKey' { $UniqueComputerNames | Should BeExactly 'localhost' } - It 'should not return a computer name when not using a CIM session' { - $Result = Get-CSRegistryKey -Hive HKLM | Select -First 1 - - $Result.PSComputerName | Should BeNullOrEmpty - } - It 'should return nothing upon querying a nonexistent key' { Get-CSRegistryKey -Hive HKCU -SubKey 'nonexistentkey' | Should BeNullOrEmpty } @@ -150,8 +144,6 @@ Describe 'Get-CSRegistryValue' { $CurrentVersion | Should Not BeNullOrEmpty $CurrentVersion.ValueContent | Should Not BeNullOrEmpty - - $CurrentVersion.PSComputerName | Should BeNullOrEmpty } It 'should return value contents for an entire subkey: using -Hive and -SubKey w/ CIM Sessions' { @@ -171,8 +163,6 @@ Describe 'Get-CSRegistryValue' { $CurrentVersion | Should Not BeNullOrEmpty $CurrentVersion.ValueContent | Should Not BeNullOrEmpty - - $CurrentVersion.PSComputerName | Should BeNullOrEmpty } It 'should return value contents for a specific subkey value: using -Hive and -SubKey w/ CIM Sessions' { @@ -192,8 +182,6 @@ Describe 'Get-CSRegistryValue' { $CurrentVersion | Should Not BeNullOrEmpty $CurrentVersion.ValueContent | Should BeNullOrEmpty - - $CurrentVersion.PSComputerName | Should BeNullOrEmpty } It 'should return only value names for an entire subkey: using -Hive and -SubKey w/ CIM Sessions' { @@ -214,8 +202,6 @@ Describe 'Get-CSRegistryValue' { $CurrentVersion | Should Not BeNullOrEmpty $CurrentVersion.ValueContent | Should Not BeNullOrEmpty - - $CurrentVersion.PSComputerName | Should BeNullOrEmpty } It 'should return value contents via receiving value names over the pipeline (from Get-CSRegistryValue) for an entire subkey: using -Hive and -SubKey w/ CIM Sessions' { @@ -234,8 +220,6 @@ Describe 'Get-CSRegistryValue' { $CurrentVersion | Should Not BeNullOrEmpty $CurrentVersion.ValueContent | Should Not BeNullOrEmpty - - $CurrentVersion.PSComputerName | Should BeNullOrEmpty } It 'should return value contents via receiving a value name over the pipeline (from Get-CSRegistryValue) for a specific subkey value: using -Hive and -SubKey w/ CIM Sessions' { @@ -254,8 +238,6 @@ Describe 'Get-CSRegistryValue' { $CurrentVersion | Should Not BeNullOrEmpty $CurrentVersion.ValueContent | Should Not BeNullOrEmpty - - $CurrentVersion.PSComputerName | Should BeNullOrEmpty } It 'should return value contents via receiving subkeys over the pipeline (from Get-CSRegistryKey) for an entire subkey: using -Hive and -SubKey w/ CIM Sessions' { @@ -274,8 +256,6 @@ Describe 'Get-CSRegistryValue' { $CurrentVersion | Should Not BeNullOrEmpty $CurrentVersion.ValueContent | Should Not BeNullOrEmpty - - $CurrentVersion.PSComputerName | Should BeNullOrEmpty } It 'should return value contents via receiving subkeys over the pipeline (from Get-CSRegistryKey) for a specific subkey value: using -Hive and -SubKey w/ CIM Sessions' { @@ -294,8 +274,6 @@ Describe 'Get-CSRegistryValue' { $CurrentVersion | Should Not BeNullOrEmpty $CurrentVersion.ValueContent | Should BeNullOrEmpty - - $CurrentVersion.PSComputerName | Should BeNullOrEmpty } It 'should return value names only via receiving subkeys over the pipeline (from Get-CSRegistryKey) for an entire subkey: using -Hive and -SubKey w/ CIM Sessions' { @@ -324,7 +302,6 @@ Describe 'Get-CSRegistryValue' { $Result.SubKey | Should BeExactly $CurrentVersionPath $Result.ValueName | Should BeExactly 'CurrentVersion' $Result.ValueContent | Should Not BeNullOrEmpty - $Result.PSComputerName | Should BeNullOrEmpty } } } @@ -334,7 +311,6 @@ Describe 'Get-CSEventLog' { $Result = Get-CSEventLog | Select -First 1 $Result.LogName | Should Not BeNullOrEmpty - $Result.PSComputerName | Should BeNullOrEmpty } It 'should return output with CIM sessions' { @@ -348,7 +324,6 @@ Describe 'Get-CSEventLog' { $Result = Get-CSEventLog -OperationTimeoutSec 3 | Select -First 1 $Result.LogName | Should Not BeNullOrEmpty - $Result.PSComputerName | Should BeNullOrEmpty } It 'should return output with CIM sessions and accept -OperationTimeoutSec' { @@ -481,7 +456,6 @@ Describe 'Get-CSMountedVolumeDriveLetter' { $Drive | Should Not BeNullOrEmpty $Drive.DriveLetter | Should Match '^[A-Z]$' $Drive.DirectoryPath | Should Match "^$($Drive.DriveLetter):\\`$" - $Drive.PSComputerName | Should BeNullOrEmpty } It 'should return at least one mounted partition w/ CIM sessions' { @@ -499,7 +473,6 @@ Describe 'Get-CSMountedVolumeDriveLetter' { $Drive | Should Not BeNullOrEmpty $Drive.DriveLetter | Should Match '^[A-Z]$' $Drive.DirectoryPath | Should Match "^$($Drive.DriveLetter):\\`$" - $Drive.PSComputerName | Should BeNullOrEmpty } } @@ -998,7 +971,6 @@ Describe 'Get-CSEnvironmentVariable' { $EnvVar.Name | Should Not BeNullOrEmpty $EnvVar.User | Should Not BeNullOrEmpty $EnvVar.VariableValue | Should Not BeNullOrEmpty - $EnvVar.PSComputerName | Should BeNullOrEmpty } It 'should return a populated environment variable w/ CIM sessions' { @@ -1016,7 +988,6 @@ Describe 'Get-CSEnvironmentVariable' { $EnvVar.Name | Should Not BeNullOrEmpty $EnvVar.User | Should BeExactly '' $EnvVar.VariableValue | Should Not BeNullOrEmpty - $EnvVar.PSComputerName | Should BeNullOrEmpty } It 'should return a populated system environment variable w/ CIM sessions' { @@ -1035,7 +1006,6 @@ Describe 'Get-CSEnvironmentVariable' { $EnvVar.User | Should Not BeNullOrEmpty $EnvVar.User | Should Not Be '' $EnvVar.VariableValue | Should Not BeNullOrEmpty - $EnvVar.PSComputerName | Should BeNullOrEmpty } It 'should return a populated user environment variable w/ CIM sessions' { @@ -1054,7 +1024,6 @@ Describe 'Get-CSEnvironmentVariable' { $EnvVar.Name | Should BeExactly 'TEMP' $EnvVar.User | Should Not BeNullOrEmpty $EnvVar.VariableValue | Should Not BeNullOrEmpty - $EnvVar.PSComputerName | Should BeNullOrEmpty } It 'should return a named environment variable w/ CIM sessions' { @@ -1072,7 +1041,6 @@ Describe 'Get-CSEnvironmentVariable' { $EnvVar.Name | Should BeExactly 'TEMP' $EnvVar.User | Should BeExactly '' $EnvVar.VariableValue | Should Not BeNullOrEmpty - $EnvVar.PSComputerName | Should BeNullOrEmpty } It 'should return a named system environment variable w/ CIM sessions' { @@ -1091,7 +1059,6 @@ Describe 'Get-CSEnvironmentVariable' { $EnvVar.User | Should Not BeNullOrEmpty $EnvVar.User | Should Not Be '' $EnvVar.VariableValue | Should Not BeNullOrEmpty - $EnvVar.PSComputerName | Should BeNullOrEmpty } It 'should return a named user environment variable w/ CIM sessions' { From d7fbda3dfb27d15e4c0e0be61e163e5c63e0335d Mon Sep 17 00:00:00 2001 From: Matt Graeber Date: Fri, 28 Oct 2016 16:42:59 -0700 Subject: [PATCH 07/15] Removed -OperationTimeoutSec param from all functions. Was creating unnecessary code complexity. --- CimSweep/CimSweep.psd1 | 6 +- CimSweep/Core/CoreFunctions.ps1 | 213 ++++-------------------- CimSweep/Defense/AppCompatDatabases.ps1 | 25 +-- CimSweep/Defense/Autoruns.ps1 | 161 +++++++----------- CimSweep/Defense/Bitlocker.ps1 | 14 +- CimSweep/Defense/SuspiciousFiles.ps1 | 61 +++---- CimSweep/Defense/SuspiciousURLs.ps1 | 19 +-- CimSweep/Offense/ACLAudits.ps1 | 19 +-- CimSweep/Offense/AntiVirusInfo.ps1 | 23 +-- CimSweep/Offense/ProxyConfig.ps1 | 16 +- CimSweep/Tests/Core.CimSweep.Tests.ps1 | 36 ---- CimSweep/Tests/Module.Tests.ps1 | 11 +- README.md | 17 +- 13 files changed, 148 insertions(+), 473 deletions(-) diff --git a/CimSweep/CimSweep.psd1 b/CimSweep/CimSweep.psd1 index ed7ec45..e4d8dab 100644 --- a/CimSweep/CimSweep.psd1 +++ b/CimSweep/CimSweep.psd1 @@ -1,7 +1,7 @@ @{ RootModule = 'CimSweep.psm1' -ModuleVersion = '0.5.2.0' +ModuleVersion = '0.6.0.0' GUID = 'f347ef1c-d752-4d07-bf68-3197c0aa661a' @@ -50,7 +50,7 @@ PrivateData = @{ ProjectUri = 'https://github.com/PowerShellMafia/CimSweep' ReleaseNotes = @' -0.5.2 +0.6.0 ----- Enhancements: * Added Get-CSInstalledAppCompatShimDatabase @@ -58,6 +58,8 @@ Enhancements: Removed: * Removed the -NoProgressBar parameter from all functions since this is what $ProgressPreference is for. +* Removed Set-DefaultDisplayProperty helper function and all calls to it. It was creating unnecessary code complexity. +* Removed -OperationTimeoutSec param from all functions. Was creating unnecessary code complexity. 0.5.1 ----- diff --git a/CimSweep/Core/CoreFunctions.ps1 b/CimSweep/Core/CoreFunctions.ps1 index 5046af8..ed4630f 100644 --- a/CimSweep/Core/CoreFunctions.ps1 +++ b/CimSweep/Core/CoreFunctions.ps1 @@ -31,14 +31,6 @@ Gets the registry keys in the specified subkey as well as all child keys. Specifies the CIM session to use for this cmdlet. Enter a variable that contains the CIM session or a command that creates or gets the CIM session, such as the New-CimSession or Get-CimSession cmdlets. For more information, see about_CimSessions. -.PARAMETER OperationTimeoutSec - -Specifies the amount of time that the cmdlet waits for a response from the computer. - -By default, the value of this parameter is 0, which means that the cmdlet uses the default timeout value for the server. - -If the OperationTimeoutSec parameter is set to a value less than the robust connection retry timeout of 3 minutes, network failures that last more than the value of the OperationTimeoutSec parameter are not recoverable, because the operation on the server times out before the client can reconnect. - .EXAMPLE Get-CSRegistryKey -Hive HKLM @@ -97,11 +89,7 @@ It is not recommended to recursively list all registry keys from most parent key [Parameter(ValueFromPipelineByPropertyName = $True)] [Alias('Session')] [Microsoft.Management.Infrastructure.CimSession[]] - $CimSession, - - [UInt32] - [Alias('OT')] - $OperationTimeoutSec + $CimSession ) BEGIN { @@ -112,9 +100,6 @@ It is not recommended to recursively list all registry keys from most parent key $AddAcl = @{} if ($PSBoundParameters['IncludeAcl']) { $AddAcl['IncludeAcl'] = $True } - - $Timeout = @{} - if ($PSBoundParameters['OperationTimeoutSec']) { $Timeout['OperationTimeoutSec'] = $OperationTimeoutSec } } PROCESS { @@ -149,7 +134,7 @@ It is not recommended to recursively list all registry keys from most parent key $CimMethodArgs['Arguments'] = $RegistryMethodArgs - $Result = Invoke-CimMethod @CimMethodArgs @Timeout + $Result = Invoke-CimMethod @CimMethodArgs if ($Result.sNames) { foreach ($KeyName in $Result.sNames) { @@ -214,7 +199,7 @@ It is not recommended to recursively list all registry keys from most parent key $ObjectProperties.Remove('PSTypeName') $ObjectProperties.Remove('PSComputerName') $ObjectProperties.Remove('ACL') - Get-CSRegistryKey @ObjectProperties @Timeout @AddAcl -Recurse + Get-CSRegistryKey @ObjectProperties @AddAcl -Recurse } } } @@ -259,14 +244,6 @@ Specifies that the content of the registry value should not be received. This sw Specifies the CIM session to use for this cmdlet. Enter a variable that contains the CIM session or a command that creates or gets the CIM session, such as the New-CimSession or Get-CimSession cmdlets. For more information, see about_CimSessions. -.PARAMETER OperationTimeoutSec - -Specifies the amount of time that the cmdlet waits for a response from the computer. - -By default, the value of this parameter is 0, which means that the cmdlet uses the default timeout value for the server. - -If the OperationTimeoutSec parameter is set to a value less than the robust connection retry timeout of 3 minutes, network failures that last more than the value of the OperationTimeoutSec parameter are not recoverable, because the operation on the server times out before the client can reconnect. - .EXAMPLE Get-CSRegistryValue -Hive HKCU -SubKey SOFTWARE\Microsoft\Windows\CurrentVersion\Run @@ -349,11 +326,7 @@ Outputs a list of objects representing registry value names, their respective ty [Parameter(ValueFromPipelineByPropertyName = $True)] [Alias('Session')] [Microsoft.Management.Infrastructure.CimSession[]] - $CimSession, - - [UInt32] - [Alias('OT')] - $OperationTimeoutSec + $CimSession ) BEGIN { @@ -362,9 +335,6 @@ Outputs a list of objects representing registry value names, their respective ty $CimSession = '' } - $Timeout = @{} - if ($PSBoundParameters['OperationTimeoutSec']) { $Timeout['OperationTimeoutSec'] = $OperationTimeoutSec } - $Type = @{ 0 = 'REG_NONE' 1 = 'REG_SZ' @@ -465,7 +435,7 @@ Outputs a list of objects representing registry value names, their respective ty $ValueContent = $null if (-not $PSBoundParameters['ValueNameOnly']) { - $Result = Invoke-CimMethod @CimMethodArgs @Timeout + $Result = Invoke-CimMethod @CimMethodArgs if ($Result.ReturnValue -eq 0) { $ValueContent = $Result."$ReturnProp" @@ -495,7 +465,7 @@ Outputs a list of objects representing registry value names, their respective ty $CimMethodArgs['Arguments'] = $RegistryMethodArgs - $Result = Invoke-CimMethod @CimMethodArgs @Timeout + $Result = Invoke-CimMethod @CimMethodArgs # Only progress if EnumValues returns actual value and type data if ($Result.Types.Length) { @@ -584,7 +554,7 @@ Outputs a list of objects representing registry value names, their respective ty $ValueContent = $null if (-not $PSBoundParameters['ValueNameOnly']) { - $Result2 = Invoke-CimMethod @CimMethod2Args @Timeout + $Result2 = Invoke-CimMethod @CimMethod2Args if ($Result2.ReturnValue -eq 0) { $ValueContent = $Result2."$ReturnProp" @@ -629,14 +599,6 @@ Get-CSEventLog lists the available event logs from which event entries can be re Specifies the CIM session to use for this cmdlet. Enter a variable that contains the CIM session or a command that creates or gets the CIM session, such as the New-CimSession or Get-CimSession cmdlets. For more information, see about_CimSessions. -.PARAMETER OperationTimeoutSec - -Specifies the amount of time that the cmdlet waits for a response from the computer. - -By default, the value of this parameter is 0, which means that the cmdlet uses the default timeout value for the server. - -If the OperationTimeoutSec parameter is set to a value less than the robust connection retry timeout of 3 minutes, network failures that last more than the value of the OperationTimeoutSec parameter are not recoverable, because the operation on the server times out before the client can reconnect. - .NOTES Get-CSEventLog is useful for determining which event log to filter off of in Get-CSEventLogEntry. @@ -666,11 +628,7 @@ Outputs objects representing the available event logs which can be piped to Get- [Alias('Session')] [ValidateNotNullOrEmpty()] [Microsoft.Management.Infrastructure.CimSession[]] - $CimSession, - - [UInt32] - [Alias('OT')] - $OperationTimeoutSec + $CimSession ) BEGIN { @@ -683,9 +641,6 @@ Outputs objects representing the available event logs which can be piped to Get- } $CurrentCIMSession = 0 - - $Timeout = @{} - if ($PSBoundParameters['OperationTimeoutSec']) { $Timeout['OperationTimeoutSec'] = $OperationTimeoutSec } } PROCESS { @@ -701,7 +656,7 @@ Outputs objects representing the available event logs which can be piped to Get- if ($Session.Id) { $CommonArgs['CimSession'] = $Session } - Get-CimInstance -ClassName Win32_NTEventlogFile -Property LogfileName @CommonArgs @Timeout | ForEach-Object { + Get-CimInstance -ClassName Win32_NTEventlogFile -Property LogfileName @CommonArgs | ForEach-Object { $ObjectProperties = [Ordered] @{ PSTypeName = 'CimSweep.EventLog' LogName = $_.LogfileName @@ -783,14 +738,6 @@ Specifies the desired properties to retrieve from Win32_Process instances. The f Specifies the CIM session to use for this cmdlet. Enter a variable that contains the CIM session or a command that creates or gets the CIM session, such as the New-CimSession or Get-CimSession cmdlets. For more information, see about_CimSessions. -.PARAMETER OperationTimeoutSec - -Specifies the amount of time that the cmdlet waits for a response from the computer. - -By default, the value of this parameter is 0, which means that the cmdlet uses the default timeout value for the server. - -If the OperationTimeoutSec parameter is set to a value less than the robust connection retry timeout of 3 minutes, network failures that last more than the value of the OperationTimeoutSec parameter are not recoverable, because the operation on the server times out before the client can reconnect. - .EXAMPLE Get-CSEventLogEntry @@ -907,11 +854,7 @@ Outputs Win32_NtLogEvent instances. [Alias('Session')] [ValidateNotNullOrEmpty()] [Microsoft.Management.Infrastructure.CimSession[]] - $CimSession, - - [UInt32] - [Alias('OT')] - $OperationTimeoutSec + $CimSession ) BEGIN { @@ -927,9 +870,6 @@ Outputs Win32_NtLogEvent instances. $PropertyList = @{} if ($PSBoundParameters['LimitOutput'] -or $PSBoundParameters['Property']) { $PropertyList['Property'] = $Property } - - $Timeout = @{} - if ($PSBoundParameters['OperationTimeoutSec']) { $Timeout['OperationTimeoutSec'] = $OperationTimeoutSec } } PROCESS { @@ -978,7 +918,7 @@ Outputs Win32_NtLogEvent instances. $EventLogEntryArgs['Filter'] = $Filter } - Get-CimInstance -ClassName Win32_NTLogEvent @CommonArgs @EventLogEntryArgs @PropertyList @Timeout + Get-CimInstance -ClassName Win32_NTLogEvent @CommonArgs @EventLogEntryArgs @PropertyList } } } @@ -1000,14 +940,6 @@ Get-CSMountedVolumeDriveLetter lists the drive letters of mounted drives. This i Specifies the CIM session to use for this cmdlet. Enter a variable that contains the CIM session or a command that creates or gets the CIM session, such as the New-CimSession or Get-CimSession cmdlets. For more information, see about_CimSessions. -.PARAMETER OperationTimeoutSec - -Specifies the amount of time that the cmdlet waits for a response from the computer. - -By default, the value of this parameter is 0, which means that the cmdlet uses the default timeout value for the server. - -If the OperationTimeoutSec parameter is set to a value less than the robust connection retry timeout of 3 minutes, network failures that last more than the value of the OperationTimeoutSec parameter are not recoverable, because the operation on the server times out before the client can reconnect. - .EXAMPLE Get-CSMountedVolumeDriveLetter @@ -1033,11 +965,7 @@ Outputs a list of mounted drive letters. [Alias('Session')] [ValidateNotNullOrEmpty()] [Microsoft.Management.Infrastructure.CimSession[]] - $CimSession, - - [UInt32] - [Alias('OT')] - $OperationTimeoutSec + $CimSession ) BEGIN { @@ -1045,9 +973,6 @@ Outputs a list of mounted drive letters. if (-not $PSBoundParameters['CimSession']) { $CimSession = '' } - - $Timeout = @{} - if ($PSBoundParameters['OperationTimeoutSec']) { $Timeout['OperationTimeoutSec'] = $OperationTimeoutSec } } PROCESS { @@ -1059,7 +984,7 @@ Outputs a list of mounted drive letters. if ($Session.Id) { $CommonArgs['CimSession'] = $Session } - $Result = Get-CimInstance -ClassName Win32_LogicalDisk -Property DeviceID @CommonArgs @Timeout + $Result = Get-CimInstance -ClassName Win32_LogicalDisk -Property DeviceID @CommonArgs foreach ($Volume in $Result) { if ($Volume.DeviceID) { @@ -1172,14 +1097,6 @@ Recurse on all child directories. Specifies the CIM session to use for this cmdlet. Enter a variable that contains the CIM session or a command that creates or gets the CIM session, such as the New-CimSession or Get-CimSession cmdlets. For more information, see about_CimSessions. -.PARAMETER OperationTimeoutSec - -Specifies the amount of time that the cmdlet waits for a response from the computer. - -By default, the value of this parameter is 0, which means that the cmdlet uses the default timeout value for the server. - -If the OperationTimeoutSec parameter is set to a value less than the robust connection retry timeout of 3 minutes, network failures that last more than the value of the OperationTimeoutSec parameter are not recoverable, because the operation on the server times out before the client can reconnect. - .EXAMPLE Get-CSDirectoryListing @@ -1324,11 +1241,7 @@ Filter parameters in Get-CSDirectoryListing only apply to files, not directories [Parameter(ValueFromPipelineByPropertyName = $True)] [Alias('Session')] [Microsoft.Management.Infrastructure.CimSession[]] - $CimSession, - - [UInt32] - [Alias('OT')] - $OperationTimeoutSec + $CimSession ) BEGIN { @@ -1336,9 +1249,6 @@ Filter parameters in Get-CSDirectoryListing only apply to files, not directories if (-not $PSBoundParameters['CimSession']) { $CimSession = '' } - - $Timeout = @{} - if ($PSBoundParameters['OperationTimeoutSec']) { $Timeout['OperationTimeoutSec'] = $OperationTimeoutSec } } PROCESS { @@ -1380,7 +1290,7 @@ Filter parameters in Get-CSDirectoryListing only apply to files, not directories # Only obtain directory information if -File was not specified if (-not $PSBoundParameters['File']) { # Get all directories present in the specified folder - Get-CimInstance @CommonArgs @DirArguments @Timeout | ForEach-Object { + Get-CimInstance @CommonArgs @DirArguments | ForEach-Object { $DirObject = $_ # Append the CimSession instance. This enables piping Get-CSDirectoryListing to itself @@ -1494,7 +1404,7 @@ Filter parameters in Get-CSDirectoryListing only apply to files, not directories } # Get all files present in the specified folder - Get-CimInstance @CommonArgs @FileArguments @Timeout | ForEach-Object { + Get-CimInstance @CommonArgs @FileArguments | ForEach-Object { $Object = $_ Add-Member -InputObject $Object -MemberType NoteProperty -Name CimSession -Value $CimSession @@ -1611,14 +1521,6 @@ Specifies that the ACL file hosting the service be returned. -IncludeFileInfo wi Specifies the CIM session to use for this cmdlet. Enter a variable that contains the CIM session or a command that creates or gets the CIM session, such as the New-CimSession or Get-CimSession cmdlets. For more information, see about_CimSessions. -.PARAMETER OperationTimeoutSec - -Specifies the amount of time that the cmdlet waits for a response from the computer. - -By default, the value of this parameter is 0, which means that the cmdlet uses the default timeout value for the server. - -If the OperationTimeoutSec parameter is set to a value less than the robust connection retry timeout of 3 minutes, network failures that last more than the value of the OperationTimeoutSec parameter are not recoverable, because the operation on the server times out before the client can reconnect. - .EXAMPLE Get-CSService @@ -1741,11 +1643,7 @@ Outputs Win32_Service or Win32_SystemDriver instances both of which derive from [Alias('Session')] [ValidateNotNullOrEmpty()] [Microsoft.Management.Infrastructure.CimSession[]] - $CimSession, - - [UInt32] - [Alias('OT')] - $OperationTimeoutSec + $CimSession ) BEGIN { @@ -1762,9 +1660,6 @@ Outputs Win32_Service or Win32_SystemDriver instances both of which derive from $PropertyList = @{} if ($PSBoundParameters['LimitOutput'] -or $PSBoundParameters['Property']) { $PropertyList['Property'] = $Property } - $Timeout = @{} - if ($PSBoundParameters['OperationTimeoutSec']) { $Timeout['OperationTimeoutSec'] = $OperationTimeoutSec } - <# # This won't compile using Add-Type in Nano Server TP5 due to # a bug where it cannot determine the proper framework dir. @@ -1904,7 +1799,7 @@ Outputs Win32_Service or Win32_SystemDriver instances both of which derive from if ($UserModeServices -and (-not $Drivers)) { $ClassName = 'Win32_Service' } if ($Drivers -and (-not $UserModeServices)) { $ClassName = 'Win32_SystemDriver' } - Get-CimInstance -ClassName $ClassName @CommonArgs @ServiceEntryArgs @PropertyList @Timeout | ForEach-Object { + Get-CimInstance -ClassName $ClassName @CommonArgs @ServiceEntryArgs @PropertyList | ForEach-Object { $CurrentService = $_ $IsWin32Service = $CurrentService.PSTypeNames -contains 'Microsoft.Management.Infrastructure.CimInstance#root/cimv2/Win32_Service' @@ -2051,14 +1946,6 @@ Specifies the desired properties to retrieve from Win32_Process instances. The f Specifies the CIM session to use for this cmdlet. Enter a variable that contains the CIM session or a command that creates or gets the CIM session, such as the New-CimSession or Get-CimSession cmdlets. For more information, see about_CimSessions. -.PARAMETER OperationTimeoutSec - -Specifies the amount of time that the cmdlet waits for a response from the computer. - -By default, the value of this parameter is 0, which means that the cmdlet uses the default timeout value for the server. - -If the OperationTimeoutSec parameter is set to a value less than the robust connection retry timeout of 3 minutes, network failures that last more than the value of the OperationTimeoutSec parameter are not recoverable, because the operation on the server times out before the client can reconnect. - .EXAMPLE Get-CSProcess @@ -2179,11 +2066,7 @@ Outputs Win32_Process instances. [Alias('Session')] [ValidateNotNullOrEmpty()] [Microsoft.Management.Infrastructure.CimSession[]] - $CimSession, - - [UInt32] - [Alias('OT')] - $OperationTimeoutSec + $CimSession ) BEGIN { @@ -2197,9 +2080,6 @@ Outputs Win32_Process instances. $CurrentCIMSession = 0 - $Timeout = @{} - if ($PSBoundParameters['OperationTimeoutSec']) { $Timeout['OperationTimeoutSec'] = $OperationTimeoutSec } - $PropertyList = @{} if ($PSBoundParameters['LimitOutput'] -or $PSBoundParameters['Property']) { $PropertyList['Property'] = $Property } } @@ -2232,7 +2112,7 @@ Outputs Win32_Process instances. $ProcessEntryArgs['Filter'] = $Filter } - Get-CimInstance -ClassName Win32_Process @CommonArgs @ProcessEntryArgs @PropertyList @Timeout + Get-CimInstance -ClassName Win32_Process @CommonArgs @ProcessEntryArgs @PropertyList } } } @@ -2266,14 +2146,6 @@ Specifies that only user-scope environment variables should be returned. Specifies the CIM session to use for this cmdlet. Enter a variable that contains the CIM session or a command that creates or gets the CIM session, such as the New-CimSession or Get-CimSession cmdlets. For more information, see about_CimSessions. -.PARAMETER OperationTimeoutSec - -Specifies the amount of time that the cmdlet waits for a response from the computer. - -By default, the value of this parameter is 0, which means that the cmdlet uses the default timeout value for the server. - -If the OperationTimeoutSec parameter is set to a value less than the robust connection retry timeout of 3 minutes, network failures that last more than the value of the OperationTimeoutSec parameter are not recoverable, because the operation on the server times out before the client can reconnect. - .EXAMPLE Get-CSEnvironmentVariable @@ -2332,11 +2204,7 @@ Outputs objects consisting of the name, value, and scope (user vs. system) of an [Alias('Session')] [ValidateNotNullOrEmpty()] [Microsoft.Management.Infrastructure.CimSession[]] - $CimSession, - - [UInt32] - [Alias('OT')] - $OperationTimeoutSec + $CimSession ) BEGIN { @@ -2374,7 +2242,7 @@ Outputs objects consisting of the name, value, and scope (user vs. system) of an # Performance enhancements are realized when specifying a specific environment variable name. if ($PSBoundParameters['VariableName']) { if (($PSCmdlet.ParameterSetName -eq 'System') -or ($PSCmdlet.ParameterSetName -eq 'Default')) { - $Result = Get-CSRegistryValue -Hive HKLM -SubKey $SystemEnvPath -ValueName $VariableName -ValueType REG_SZ @CommonArgs @Timeout + $Result = Get-CSRegistryValue -Hive HKLM -SubKey $SystemEnvPath -ValueName $VariableName -ValueType REG_SZ @CommonArgs if ($Result.ValueContent) { $ObjectProperties = [Ordered] @{ @@ -2393,11 +2261,11 @@ Outputs objects consisting of the name, value, and scope (user vs. system) of an if (($PSCmdlet.ParameterSetName -eq 'User') -or ($PSCmdlet.ParameterSetName -eq 'Default')) { # Get the SIDS for each user in the registry - $HKUSIDs = Get-HKUSID @CommonArgs @Timeout + $HKUSIDs = Get-HKUSID @CommonArgs # Iterate over each local user hive foreach ($SID in $HKUSIDs) { - $Result = Get-CSRegistryValue -Hive HKU -SubKey "$SID\Volatile Environment" -ValueName $VariableName -ValueType REG_SZ @CommonArgs @Timeout + $Result = Get-CSRegistryValue -Hive HKU -SubKey "$SID\Volatile Environment" -ValueName $VariableName -ValueType REG_SZ @CommonArgs if ($Result.ValueContent) { $ObjectProperties = [Ordered] @{ @@ -2413,7 +2281,7 @@ Outputs objects consisting of the name, value, and scope (user vs. system) of an [PSCustomObject] $ObjectProperties } else { - $Result = Get-CSRegistryValue -Hive HKU -SubKey "$SID\Environment" -ValueName $VariableName -ValueType REG_SZ @CommonArgs @Timeout + $Result = Get-CSRegistryValue -Hive HKU -SubKey "$SID\Environment" -ValueName $VariableName -ValueType REG_SZ @CommonArgs if ($Result.ValueContent) { $ObjectProperties = [Ordered] @{ @@ -2433,7 +2301,7 @@ Outputs objects consisting of the name, value, and scope (user vs. system) of an } } else { # Retrieve all environment variables if (($PSCmdlet.ParameterSetName -eq 'System') -or ($PSCmdlet.ParameterSetName -eq 'Default')) { - Get-CSRegistryValue -Hive HKLM -SubKey $SystemEnvPath @CommonArgs @Timeout | ForEach-Object { + Get-CSRegistryValue -Hive HKLM -SubKey $SystemEnvPath @CommonArgs | ForEach-Object { $ObjectProperties = [Ordered] @{ PSTypeName = $ObjectType Name = $_.ValueName @@ -2450,11 +2318,11 @@ Outputs objects consisting of the name, value, and scope (user vs. system) of an if (($PSCmdlet.ParameterSetName -eq 'User') -or ($PSCmdlet.ParameterSetName -eq 'Default')) { # Get the SIDS for each user in the registry - $HKUSIDs = Get-HKUSID @CommonArgs @Timeout + $HKUSIDs = Get-HKUSID @CommonArgs # Iterate over each local user hive foreach ($SID in $HKUSIDs) { - Get-CSRegistryValue -Hive HKU -SubKey "$SID\Volatile Environment" @CommonArgs @Timeout | ForEach-Object { + Get-CSRegistryValue -Hive HKU -SubKey "$SID\Volatile Environment" @CommonArgs | ForEach-Object { $ObjectProperties = [Ordered] @{ PSTypeName = $ObjectType Name = $_.ValueName @@ -2468,7 +2336,7 @@ Outputs objects consisting of the name, value, and scope (user vs. system) of an [PSCustomObject] $ObjectProperties } - Get-CSRegistryValue -Hive HKU -SubKey "$SID\Environment" @CommonArgs @Timeout | ForEach-Object { + Get-CSRegistryValue -Hive HKU -SubKey "$SID\Environment" @CommonArgs | ForEach-Object { $ObjectProperties = [Ordered] @{ PSTypeName = $ObjectType Name = $_.ValueName @@ -2517,14 +2385,6 @@ Specifies that the ACL for the namespace should be returned. -IncludeAcl will ap Specifies the CIM session to use for this cmdlet. Enter a variable that contains the CIM session or a command that creates or gets the CIM session, such as the New-CimSession or Get-CimSession cmdlets. For more information, see about_CimSessions. -.PARAMETER OperationTimeoutSec - -Specifies the amount of time that the cmdlet waits for a response from the computer. - -By default, the value of this parameter is 0, which means that the cmdlet uses the default timeout value for the server. - -If the OperationTimeoutSec parameter is set to a value less than the robust connection retry timeout of 3 minutes, network failures that last more than the value of the OperationTimeoutSec parameter are not recoverable, because the operation on the server times out before the client can reconnect. - .EXAMPLE Get-CSWmiNamespace @@ -2570,11 +2430,7 @@ Microsoft.Management.Infrastructure.CimInstance#root/__NAMESPACE [Alias('Session')] [ValidateNotNullOrEmpty()] [Microsoft.Management.Infrastructure.CimSession[]] - $CimSession, - - [UInt32] - [Alias('OT')] - $OperationTimeoutSec + $CimSession ) BEGIN { @@ -2583,9 +2439,6 @@ Microsoft.Management.Infrastructure.CimInstance#root/__NAMESPACE $CimSession = '' } - $Timeout = @{} - if ($PSBoundParameters['OperationTimeoutSec']) { $Timeout['OperationTimeoutSec'] = $OperationTimeoutSec } - $RecurseArg = @{} if ($Recurse) { $RecurseArg['Recurse'] = $True } @@ -2674,7 +2527,7 @@ Microsoft.Management.Infrastructure.CimInstance#root/__NAMESPACE MethodName = 'GetSecurityDescriptor' } - $GetSDResult = Invoke-CimMethod @GetSDArgs @CommonArgs @Timeout -ErrorAction SilentlyContinue + $GetSDResult = Invoke-CimMethod @GetSDArgs @CommonArgs -ErrorAction SilentlyContinue if ($GetSDResult.ReturnValue -eq 0) { $Win32SDToBinarySDArgs = @{ @@ -2685,7 +2538,7 @@ Microsoft.Management.Infrastructure.CimInstance#root/__NAMESPACE } } - $ConversionResult = Invoke-CimMethod @Win32SDToBinarySDArgs @CommonArgs @Timeout + $ConversionResult = Invoke-CimMethod @Win32SDToBinarySDArgs @CommonArgs if ($ConversionResult.ReturnValue -eq 0) { $NamespaceSD = [Activator]::CreateInstance($NamespaceSecurityType) @@ -2705,7 +2558,7 @@ Microsoft.Management.Infrastructure.CimInstance#root/__NAMESPACE $_ if ($Recurse) { - Get-CSWmiNamespace -Namespace $FullyQualifiedNamespace @CommonArgs @RecurseArg @IncludeAclArg @Timeout + Get-CSWmiNamespace -Namespace $FullyQualifiedNamespace @CommonArgs @RecurseArg @IncludeAclArg } } } diff --git a/CimSweep/Defense/AppCompatDatabases.ps1 b/CimSweep/Defense/AppCompatDatabases.ps1 index 047ef61..fc3e4bb 100644 --- a/CimSweep/Defense/AppCompatDatabases.ps1 +++ b/CimSweep/Defense/AppCompatDatabases.ps1 @@ -15,14 +15,6 @@ Get-InstalledAppCompatShimDatabase lists details about all installed application Specifies the CIM session to use for this cmdlet. Enter a variable that contains the CIM session or a command that creates or gets the CIM session, such as the New-CimSession or Get-CimSession cmdlets. For more information, see about_CimSessions. -.PARAMETER OperationTimeoutSec - -Specifies the amount of time that the cmdlet waits for a response from the computer. - -By default, the value of this parameter is 0, which means that the cmdlet uses the default timeout value for the server. - -If the OperationTimeoutSec parameter is set to a value less than the robust connection retry timeout of 3 minutes, network failures that last more than the value of the OperationTimeoutSec parameter are not recoverable, because the operation on the server times out before the client can reconnect. - .EXAMPLE Get-CSRegistryAutoStart @@ -42,11 +34,7 @@ Outputs objects representing the relevant information regarding installed applic [Alias('Session')] [ValidateNotNullOrEmpty()] [Microsoft.Management.Infrastructure.CimSession[]] - $CimSession, - - [UInt32] - [Alias('OT')] - $OperationTimeoutSec + $CimSession ) BEGIN { @@ -59,9 +47,6 @@ Outputs objects representing the relevant information regarding installed applic } $CurrentCIMSession = 0 - - $Timeout = @{} - if ($PSBoundParameters['OperationTimeoutSec']) { $Timeout['OperationTimeoutSec'] = $OperationTimeoutSec } } PROCESS { @@ -78,10 +63,10 @@ Outputs objects representing the relevant information regarding installed applic if ($Session.Id) { $CommonArgs['CimSession'] = $Session } # Collect all of the GUIDs for which each shimmed executable is associated. - $ShimmedExecutablesTable = Get-CSRegistryKey -Hive HKLM -SubKey 'SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Custom' @CommonArgs @Timeout | + $ShimmedExecutablesTable = Get-CSRegistryKey -Hive HKLM -SubKey 'SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Custom' @CommonArgs | Get-CSRegistryValue -ValueNameOnly | Group-Object -Property ValueName -AsHashTable - $InstalledSdb = Get-CSRegistryKey -Hive HKLM -SubKey 'SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\InstalledSdb' @CommonArgs @Timeout + $InstalledSdb = Get-CSRegistryKey -Hive HKLM -SubKey 'SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\InstalledSdb' @CommonArgs $CurrentSdb = 0 foreach ($Database in $InstalledSdb) { @@ -95,13 +80,13 @@ Outputs objects representing the relevant information regarding installed applic $DatabasePath = $DatabaseDetails['DatabasePath'].ValueContent $DatabasePathDir = Split-Path -Path $DatabasePath -Parent $DatabasePathFileName = Split-Path -Path $DatabasePath -Leaf - $DatabaseFileInfo = Get-CSDirectoryListing -DirectoryPath $DatabasePathDir -FileName $DatabasePathFileName @CommonArgs @Timeout + $DatabaseFileInfo = Get-CSDirectoryListing -DirectoryPath $DatabasePathDir -FileName $DatabasePathFileName @CommonArgs $ShimmedExecutables = $ShimmedExecutablesTable["$GUID.sdb"] | ForEach-Object { $_.Subkey.Split('\')[-1] } $IsPresentInAddRemovePrograms = $False - $Result = Get-CSRegistryValue -Hive HKLM -SubKey "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$GUID.sdb" -ValueNameOnly @CommonArgs @Timeout + $Result = Get-CSRegistryValue -Hive HKLM -SubKey "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\$GUID.sdb" -ValueNameOnly @CommonArgs if ($Result) { $IsPresentInAddRemovePrograms = $True diff --git a/CimSweep/Defense/Autoruns.ps1 b/CimSweep/Defense/Autoruns.ps1 index 9143595..3b20ddf 100644 --- a/CimSweep/Defense/Autoruns.ps1 +++ b/CimSweep/Defense/Autoruns.ps1 @@ -55,14 +55,6 @@ Retrieve boot execute artifacts Specifies the CIM session to use for this cmdlet. Enter a variable that contains the CIM session or a command that creates or gets the CIM session, such as the New-CimSession or Get-CimSession cmdlets. For more information, see about_CimSessions. -.PARAMETER OperationTimeoutSec - -Specifies the amount of time that the cmdlet waits for a response from the computer. - -By default, the value of this parameter is 0, which means that the cmdlet uses the default timeout value for the server. - -If the OperationTimeoutSec parameter is set to a value less than the robust connection retry timeout of 3 minutes, network failures that last more than the value of the OperationTimeoutSec parameter are not recoverable, because the operation on the server times out before the client can reconnect. - .EXAMPLE Get-CSRegistryAutoStart @@ -124,11 +116,7 @@ Outputs objects representing autoruns entries similar to the output of Sysintern [Alias('Session')] [ValidateNotNullOrEmpty()] [Microsoft.Management.Infrastructure.CimSession[]] - $CimSession, - - [UInt32] - [Alias('OT')] - $OperationTimeoutSec + $CimSession ) BEGIN { @@ -142,9 +130,6 @@ Outputs objects representing autoruns entries similar to the output of Sysintern $CurrentCIMSession = 0 - $Timeout = @{} - if ($PSBoundParameters['OperationTimeoutSec']) { $Timeout['OperationTimeoutSec'] = $OperationTimeoutSec } - $ParamCopy = $PSBoundParameters $null = $ParamCopy.Remove('CimSession') $null = $ParamCopy.Remove('OperationTimeoutSec') @@ -224,7 +209,7 @@ Outputs objects representing autoruns entries similar to the output of Sysintern if ($Session.Id) { $CommonArgs['CimSession'] = $Session } # Get the SIDS for each user in the registry - $HKUSIDs = Get-HKUSID @CommonArgs @Timeout + $HKUSIDs = Get-HKUSID @CommonArgs if (($PSCmdlet.ParameterSetName -ne 'SpecificCheck') -or $PSBoundParameters['Logon']) { $Category = 'Logon' @@ -232,10 +217,10 @@ Outputs objects representing autoruns entries similar to the output of Sysintern Write-Progress -Id 2 -ParentId 1 -Activity " ($($CurrentAutorunCount+1)/$($AutoRunOptionCount)) Current autoruns type:" -Status $Category -PercentComplete (($CurrentAutorunCount / $AutoRunOptionCount) * 100) $CurrentAutorunCount++ - Get-CSRegistryValue -Hive HKLM -SubKey 'SYSTEM\CurrentControlSet\Control\Terminal Server\Wds\rdpwd' -ValueName StartupPrograms @CommonArgs @Timeout | + Get-CSRegistryValue -Hive HKLM -SubKey 'SYSTEM\CurrentControlSet\Control\Terminal Server\Wds\rdpwd' -ValueName StartupPrograms @CommonArgs | New-AutoRunsEntry -Category $Category - Get-CSRegistryValue -Hive HKLM -SubKey 'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon' -ValueNameOnly @CommonArgs @Timeout | + Get-CSRegistryValue -Hive HKLM -SubKey 'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon' -ValueNameOnly @CommonArgs | Where-Object { ('VmApplet', 'Userinit', 'Shell', 'TaskMan', 'AppSetup') -contains $_.ValueName } | ForEach-Object { $_ | Get-CSRegistryValue | New-AutoRunsEntry -Category $Category } @@ -248,11 +233,11 @@ Outputs objects representing autoruns entries similar to the output of Sysintern #> $GPExtensionKey = 'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\GPExtensions' - Get-CSRegistryKey -Hive HKLM -SubKey $GPExtensionKey @CommonArgs @Timeout | - Get-CSRegistryValue -ValueName DllName @Timeout | + Get-CSRegistryKey -Hive HKLM -SubKey $GPExtensionKey @CommonArgs | + Get-CSRegistryValue -ValueName DllName | ForEach-Object { $_ | New-AutoRunsEntry -SubKey $GPExtensionKey -AutoRunEntry $_.Subkey.Split('\')[-1] -Category $Category } - $AlternateShell = Get-CSRegistryValue -Hive HKLM -SubKey 'SYSTEM\CurrentControlSet\Control\SafeBoot' -ValueName AlternateShell @CommonArgs @Timeout + $AlternateShell = Get-CSRegistryValue -Hive HKLM -SubKey 'SYSTEM\CurrentControlSet\Control\SafeBoot' -ValueName AlternateShell @CommonArgs if ($AlternateShell) { $AlternateShell | New-AutoRunsEntry -AutoRunEntry $AlternateShell.ValueContent -Category $Category } @@ -264,28 +249,28 @@ Outputs objects representing autoruns entries similar to the output of Sysintern ) foreach ($AutoStartPath in $AutoStartPaths) { - Get-CSRegistryValue -Hive HKLM -SubKey $AutoStartPath @CommonArgs @Timeout | + Get-CSRegistryValue -Hive HKLM -SubKey $AutoStartPath @CommonArgs | New-AutoRunsEntry -Category $Category # Iterate over each local user hive foreach ($SID in $HKUSIDs) { - Get-CSRegistryValue -Hive HKU -SubKey "$SID\$AutoStartPath" @CommonArgs @Timeout | + Get-CSRegistryValue -Hive HKU -SubKey "$SID\$AutoStartPath" @CommonArgs | New-AutoRunsEntry -Category $Category } } $null, 'Wow6432Node\' | ForEach-Object { $InstalledComponents = "SOFTWARE\$($_)Microsoft\Active Setup\Installed Components" - Get-CSRegistryKey -Hive HKLM -SubKey $InstalledComponents @CommonArgs @Timeout - } | Get-CSRegistryValue -ValueName StubPath @Timeout | ForEach-Object { - $AutoRunEntry = $_ | Get-CSRegistryValue -ValueName '' -ValueType REG_SZ @Timeout + Get-CSRegistryKey -Hive HKLM -SubKey $InstalledComponents @CommonArgs + } | Get-CSRegistryValue -ValueName StubPath | ForEach-Object { + $AutoRunEntry = $_ | Get-CSRegistryValue -ValueName '' -ValueType REG_SZ if ($AutoRunEntry.ValueContent) { $AutoRunEntryName = $AutoRunEntry.ValueContent } else { $AutoRunEntryName = 'n/a' } $_ | New-AutoRunsEntry -SubKey $InstalledComponents -AutoRunEntry $AutoRunEntryName -Category $Category } - $IconLib = Get-CSRegistryValue -Hive HKLM -SubKey 'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows' -ValueName IconServiceLib @CommonArgs @Timeout + $IconLib = Get-CSRegistryValue -Hive HKLM -SubKey 'SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows' -ValueName IconServiceLib @CommonArgs if ($IconLib) { $IconLib | New-AutoRunsEntry -SubKey "$($IconLib.SubKey)\$($IconLib.ValueName)" -AutoRunEntry $IconLib.ValueContent -Category $Category } } @@ -296,13 +281,13 @@ Outputs objects representing autoruns entries similar to the output of Sysintern Write-Progress -Id 2 -ParentId 1 -Activity " ($($CurrentAutorunCount+1)/$($AutoRunOptionCount)) Current autoruns type:" -Status $Category -PercentComplete (($CurrentAutorunCount / $AutoRunOptionCount) * 100) $CurrentAutorunCount++ - Get-CSRegistryValue -Hive HKLM -SubKey 'SYSTEM\CurrentControlSet\Control\Session Manager' -ValueNameOnly @CommonArgs @Timeout | + Get-CSRegistryValue -Hive HKLM -SubKey 'SYSTEM\CurrentControlSet\Control\Session Manager' -ValueNameOnly @CommonArgs | Where-Object { ('BootExecute','SetupExecute','Execute','S0InitialCommand') -contains $_.ValueName } | ForEach-Object { - $_ | Get-CSRegistryValue @Timeout | Where-Object { $_.ValueContent.Count } | + $_ | Get-CSRegistryValue | Where-Object { $_.ValueContent.Count } | ForEach-Object { $_ | New-AutoRunsEntry -ImagePath "$($_.ValueContent)" -Category $Category } } - Get-CSRegistryValue -Hive HKLM -SubKey 'SYSTEM\CurrentControlSet\Control' -ValueName ServiceControlManagerExtension @CommonArgs @Timeout | + Get-CSRegistryValue -Hive HKLM -SubKey 'SYSTEM\CurrentControlSet\Control' -ValueName ServiceControlManagerExtension @CommonArgs | New-AutoRunsEntry -AutoRunEntry ServiceControlManagerExtension -Category $Category } @@ -312,8 +297,8 @@ Outputs objects representing autoruns entries similar to the output of Sysintern Write-Progress -Id 2 -ParentId 1 -Activity " ($($CurrentAutorunCount+1)/$($AutoRunOptionCount)) Current autoruns type:" -Status $Category -PercentComplete (($CurrentAutorunCount / $AutoRunOptionCount) * 100) $CurrentAutorunCount++ - Get-CSRegistryKey -Hive HKLM -SubKey 'SYSTEM\CurrentControlSet\Control\Print\Monitors' @CommonArgs @Timeout | - Get-CSRegistryValue -ValueName Driver @Timeout | ForEach-Object { + Get-CSRegistryKey -Hive HKLM -SubKey 'SYSTEM\CurrentControlSet\Control\Print\Monitors' @CommonArgs | + Get-CSRegistryValue -ValueName Driver | ForEach-Object { $_ | New-AutoRunsEntry -SubKey 'SYSTEM\CurrentControlSet\Control\Print\Monitors' -AutoRunEntry $_.SubKey.Split('\')[-1] -Category $Category } } @@ -324,7 +309,7 @@ Outputs objects representing autoruns entries similar to the output of Sysintern Write-Progress -Id 2 -ParentId 1 -Activity " ($($CurrentAutorunCount+1)/$($AutoRunOptionCount)) Current autoruns type:" -Status $Category -PercentComplete (($CurrentAutorunCount / $AutoRunOptionCount) * 100) $CurrentAutorunCount++ - $NetworkOrder = Get-CSRegistryValue -Hive HKLM -SubKey 'SYSTEM\CurrentControlSet\Control\NetworkProvider\Order' -ValueName ProviderOrder @CommonArgs @Timeout + $NetworkOrder = Get-CSRegistryValue -Hive HKLM -SubKey 'SYSTEM\CurrentControlSet\Control\NetworkProvider\Order' -ValueName ProviderOrder @CommonArgs if ($NetworkOrder.ValueContent) { $NetworkOrder.ValueContent.Split(',') | ForEach-Object { @@ -339,16 +324,16 @@ Outputs objects representing autoruns entries similar to the output of Sysintern Write-Progress -Id 2 -ParentId 1 -Activity " ($($CurrentAutorunCount+1)/$($AutoRunOptionCount)) Current autoruns type:" -Status $Category -PercentComplete (($CurrentAutorunCount / $AutoRunOptionCount) * 100) $CurrentAutorunCount++ - $SecProviders = Get-CSRegistryValue -Hive HKLM -SubKey 'SYSTEM\CurrentControlSet\Control\SecurityProviders' @CommonArgs @Timeout + $SecProviders = Get-CSRegistryValue -Hive HKLM -SubKey 'SYSTEM\CurrentControlSet\Control\SecurityProviders' @CommonArgs $SecProviders | New-AutoRunsEntry -ImagePath "$($SecProviders.ValueContent)" -Category $Category - $AuthPackages = Get-CSRegistryValue -Hive HKLM -SubKey 'SYSTEM\CurrentControlSet\Control\Lsa' -ValueName 'Authentication Packages' @CommonArgs @Timeout + $AuthPackages = Get-CSRegistryValue -Hive HKLM -SubKey 'SYSTEM\CurrentControlSet\Control\Lsa' -ValueName 'Authentication Packages' @CommonArgs $AuthPackages | New-AutoRunsEntry -ImagePath "$($AuthPackages.ValueContent)" -Category $Category - $NotPackages = Get-CSRegistryValue -Hive HKLM -SubKey 'SYSTEM\CurrentControlSet\Control\Lsa' -ValueName 'Notification Packages' @CommonArgs @Timeout + $NotPackages = Get-CSRegistryValue -Hive HKLM -SubKey 'SYSTEM\CurrentControlSet\Control\Lsa' -ValueName 'Notification Packages' @CommonArgs $NotPackages | New-AutoRunsEntry -ImagePath "$($NotPackages.ValueContent)" -Category $Category - $SecPackages = Get-CSRegistryValue -Hive HKLM -SubKey 'SYSTEM\CurrentControlSet\Control\Lsa\OSConfig' -ValueName 'Security Packages' @CommonArgs @Timeout + $SecPackages = Get-CSRegistryValue -Hive HKLM -SubKey 'SYSTEM\CurrentControlSet\Control\Lsa\OSConfig' -ValueName 'Security Packages' @CommonArgs $SecPackages | New-AutoRunsEntry -ImagePath "$($SecPackages.ValueContent)" -Category $Category } @@ -368,43 +353,43 @@ Outputs objects representing autoruns entries similar to the output of Sysintern ) foreach ($CommonKey in $CommonKeys) { - Get-CSRegistryValue -Hive HKLM -SubKey $CommonKey -ValueName '' @CommonArgs @Timeout | + Get-CSRegistryValue -Hive HKLM -SubKey $CommonKey -ValueName '' @CommonArgs | New-AutoRunsEntry -AutoRunEntry $CommonKey.Split('\')[2] -Category $Category # Iterate over each local user hive foreach ($SID in $HKUSIDs) { - Get-CSRegistryValue -Hive HKU -SubKey "$SID\$CommonKey" -ValueName '' @CommonArgs @Timeout | + Get-CSRegistryValue -Hive HKU -SubKey "$SID\$CommonKey" -ValueName '' @CommonArgs | New-AutoRunsEntry -AutoRunEntry $CommonKey.Split('\')[2] -Category $Category } } - Get-CSRegistryValue -Hive HKLM -SubKey SOFTWARE\Classes\exefile\shell\open\command -ValueName 'IsolatedCommand' @CommonArgs @Timeout | + Get-CSRegistryValue -Hive HKLM -SubKey SOFTWARE\Classes\exefile\shell\open\command -ValueName 'IsolatedCommand' @CommonArgs | New-AutoRunsEntry -Category $Category $null, 'Wow6432Node\' | ForEach-Object { - Get-CSRegistryKey -Hive HKLM -SubKey "SOFTWARE\$($_)Microsoft\Windows NT\CurrentVersion\Image File Execution Options" @CommonArgs @Timeout | - Get-CSRegistryValue -ValueName Debugger @Timeout | ForEach-Object { + Get-CSRegistryKey -Hive HKLM -SubKey "SOFTWARE\$($_)Microsoft\Windows NT\CurrentVersion\Image File Execution Options" @CommonArgs | + Get-CSRegistryValue -ValueName Debugger | ForEach-Object { $_ | New-AutoRunsEntry -AutoRunEntry $_.SubKey.Substring($_.SubKey.LastIndexOf('\') + 1) -Category $Category } - Get-CSRegistryValue -Hive HKLM -SubKey "SOFTWARE\$($_)Microsoft\Command Processor" -ValueName 'Autorun' @CommonArgs @Timeout | + Get-CSRegistryValue -Hive HKLM -SubKey "SOFTWARE\$($_)Microsoft\Command Processor" -ValueName 'Autorun' @CommonArgs | New-AutoRunsEntry -Category $Category } - $Class_exe = Get-CSRegistryValue -Hive HKLM -SubKey 'SOFTWARE\Classes\.exe' -ValueName '' -ValueType REG_SZ @CommonArgs @Timeout + $Class_exe = Get-CSRegistryValue -Hive HKLM -SubKey 'SOFTWARE\Classes\.exe' -ValueName '' -ValueType REG_SZ @CommonArgs if ($Class_exe.ValueContent) { - $OpenCommand = Get-CSRegistryValue -Hive HKLM -SubKey "SOFTWARE\Classes\$($Class_exe.ValueContent)\Shell\Open\Command" -ValueName '' -ValueType REG_SZ @CommonArgs @Timeout + $OpenCommand = Get-CSRegistryValue -Hive HKLM -SubKey "SOFTWARE\Classes\$($Class_exe.ValueContent)\Shell\Open\Command" -ValueName '' -ValueType REG_SZ @CommonArgs if ($OpenCommand.ValueContent) { $OpenCommand | New-AutoRunsEntry -Hive $Class_exe.Hive -SubKey $Class_exe.SubKey -AutoRunEntry $Class_exe.ValueContent -Category $Category } } - $Class_cmd = Get-CSRegistryValue -Hive HKLM -SubKey 'SOFTWARE\Classes\.cmd' -ValueName '' -ValueType REG_SZ @CommonArgs @Timeout + $Class_cmd = Get-CSRegistryValue -Hive HKLM -SubKey 'SOFTWARE\Classes\.cmd' -ValueName '' -ValueType REG_SZ @CommonArgs if ($Class_cmd.ValueContent) { - $OpenCommand = Get-CSRegistryValue -Hive HKLM -SubKey "SOFTWARE\Classes\$($Class_cmd.ValueContent)\Shell\Open\Command" -ValueName '' -ValueType REG_SZ @CommonArgs @Timeout + $OpenCommand = Get-CSRegistryValue -Hive HKLM -SubKey "SOFTWARE\Classes\$($Class_cmd.ValueContent)\Shell\Open\Command" -ValueName '' -ValueType REG_SZ @CommonArgs if ($OpenCommand.ValueContent) { $OpenCommand | New-AutoRunsEntry -Hive $Class_cmd.Hive -SubKey $Class_cmd.SubKey -AutoRunEntry $Class_cmd.ValueContent -Category $Category @@ -412,23 +397,23 @@ Outputs objects representing autoruns entries similar to the output of Sysintern } foreach ($SID in $HKUSIDs) { - Get-CSRegistryValue -Hive HKU -SubKey "$SID\SOFTWARE\Microsoft\Command Processor" -ValueName 'Autorun' @CommonArgs @Timeout | + Get-CSRegistryValue -Hive HKU -SubKey "$SID\SOFTWARE\Microsoft\Command Processor" -ValueName 'Autorun' @CommonArgs | New-AutoRunsEntry -Category $Category - $Class_exe = Get-CSRegistryValue -Hive HKU -SubKey "$SID\SOFTWARE\Classes\.exe" -ValueName '' -ValueType REG_SZ @CommonArgs @Timeout + $Class_exe = Get-CSRegistryValue -Hive HKU -SubKey "$SID\SOFTWARE\Classes\.exe" -ValueName '' -ValueType REG_SZ @CommonArgs if ($Class_exe.ValueContent) { - $OpenCommand = Get-CSRegistryValue -Hive HKU -SubKey "$SID\SOFTWARE\Classes\$($Class_exe.ValueContent)\Shell\Open\Command" -ValueName '' -ValueType REG_SZ @CommonArgs @Timeout + $OpenCommand = Get-CSRegistryValue -Hive HKU -SubKey "$SID\SOFTWARE\Classes\$($Class_exe.ValueContent)\Shell\Open\Command" -ValueName '' -ValueType REG_SZ @CommonArgs if ($OpenCommand.ValueContent) { $OpenCommand | New-AutoRunsEntry -Hive $Class_exe.Hive -SubKey $Class_exe.SubKey -AutoRunEntry $Class_exe.ValueContent -Category $Category } } - $Class_cmd = Get-CSRegistryValue -Hive HKU -SubKey "$SID\SOFTWARE\Classes\.cmd" -ValueName '' -ValueType REG_SZ @CommonArgs @Timeout + $Class_cmd = Get-CSRegistryValue -Hive HKU -SubKey "$SID\SOFTWARE\Classes\.cmd" -ValueName '' -ValueType REG_SZ @CommonArgs if ($Class_cmd.ValueContent) { - $OpenCommand = Get-CSRegistryValue -Hive HKU -SubKey "$SID\SOFTWARE\Classes\$($Class_cmd.ValueContent)\Shell\Open\Command" -ValueName '' -ValueType REG_SZ @CommonArgs @Timeout + $OpenCommand = Get-CSRegistryValue -Hive HKU -SubKey "$SID\SOFTWARE\Classes\$($Class_cmd.ValueContent)\Shell\Open\Command" -ValueName '' -ValueType REG_SZ @CommonArgs if ($OpenCommand.ValueContent) { $OpenCommand | New-AutoRunsEntry -Hive $Class_cmd.Hive -SubKey $Class_cmd.SubKey -AutoRunEntry $Class_cmd.ValueContent -Category $Category @@ -444,13 +429,13 @@ Outputs objects representing autoruns entries similar to the output of Sysintern $CurrentAutorunCount++ $null,'Wow6432Node\' | ForEach-Object { - Get-CSRegistryValue -Hive HKLM -SubKey "SOFTWARE\$($_)Microsoft\Windows NT\CurrentVersion\Windows" -ValueName 'AppInit_DLLs' @CommonArgs @Timeout | + Get-CSRegistryValue -Hive HKLM -SubKey "SOFTWARE\$($_)Microsoft\Windows NT\CurrentVersion\Windows" -ValueName 'AppInit_DLLs' @CommonArgs | New-AutoRunsEntry -Category $Category - Get-CSRegistryValue -Hive HKLM -SubKey "SOFTWARE\$($_)Microsoft\Command Processor" -ValueName 'Autorun' @CommonArgs @Timeout | + Get-CSRegistryValue -Hive HKLM -SubKey "SOFTWARE\$($_)Microsoft\Command Processor" -ValueName 'Autorun' @CommonArgs | New-AutoRunsEntry -Category $Category } - Get-CSRegistryValue -Hive HKLM -SubKey 'SYSTEM\CurrentControlSet\Control\Session Manager\AppCertDlls' @CommonArgs @Timeout | + Get-CSRegistryValue -Hive HKLM -SubKey 'SYSTEM\CurrentControlSet\Control\Session Manager\AppCertDlls' @CommonArgs | New-AutoRunsEntry -Category $Category } @@ -460,7 +445,7 @@ Outputs objects representing autoruns entries similar to the output of Sysintern Write-Progress -Id 2 -ParentId 1 -Activity " ($($CurrentAutorunCount+1)/$($AutoRunOptionCount)) Current autoruns type:" -Status $Category -PercentComplete (($CurrentAutorunCount / $AutoRunOptionCount) * 100) $CurrentAutorunCount++ - Get-CSRegistryValue -Hive HKLM -SubKey 'SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs' @CommonArgs @Timeout | + Get-CSRegistryValue -Hive HKLM -SubKey 'SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs' @CommonArgs | New-AutoRunsEntry -Category $Category } @@ -470,37 +455,37 @@ Outputs objects representing autoruns entries similar to the output of Sysintern Write-Progress -Id 2 -ParentId 1 -Activity " ($($CurrentAutorunCount+1)/$($AutoRunOptionCount)) Current autoruns type:" -Status $Category -PercentComplete (($CurrentAutorunCount / $AutoRunOptionCount) * 100) $CurrentAutorunCount++ - $CmdLine = Get-CSRegistryValue -Hive HKLM -SubKey 'SYSTEM\Setup' -ValueName 'CmdLine' @CommonArgs @Timeout + $CmdLine = Get-CSRegistryValue -Hive HKLM -SubKey 'SYSTEM\Setup' -ValueName 'CmdLine' @CommonArgs if ($CmdLine -and $CmdLine.ValueContent) { $CmdLine | New-AutoRunsEntry -Category $Category } 'Credential Providers', 'Credential Provider Filters', 'PLAP Providers' | - ForEach-Object { Get-CSRegistryKey -Hive HKLM -SubKey "SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\$_" @CommonArgs @Timeout } | ForEach-Object { + ForEach-Object { Get-CSRegistryKey -Hive HKLM -SubKey "SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\$_" @CommonArgs } | ForEach-Object { $LastBSIndex = $_.SubKey.LastIndexOf('\') $ParentKey = $_.SubKey.Substring(0, $LastBSIndex) $Guid = $_.SubKey.Substring($LastBSIndex + 1) if ($Guid -as [Guid]) { - $AutoRunEntry = Get-CSRegistryValue -Hive HKLM -SubKey "SOFTWARE\Classes\CLSID\$Guid" -ValueName '' -ValueType REG_SZ @CommonArgs @Timeout - $InprocServer32 = Get-CSRegistryValue -Hive HKLM -SubKey "SOFTWARE\Classes\CLSID\$Guid\InprocServer32" -ValueName '' -ValueType REG_EXPAND_SZ @CommonArgs @Timeout + $AutoRunEntry = Get-CSRegistryValue -Hive HKLM -SubKey "SOFTWARE\Classes\CLSID\$Guid" -ValueName '' -ValueType REG_SZ @CommonArgs + $InprocServer32 = Get-CSRegistryValue -Hive HKLM -SubKey "SOFTWARE\Classes\CLSID\$Guid\InprocServer32" -ValueName '' -ValueType REG_EXPAND_SZ @CommonArgs New-AutoRunsEntry $_.Hive $ParentKey $AutoRunEntry.ValueContent $InprocServer32.ValueContent $Category $_.PSComputerName } } - $BootVer = Get-CSRegistryValue -Hive HKLM -SubKey 'SYSTEM\CurrentControlSet\Control\BootVerificationProgram' -ValueName 'ImagePath' @CommonArgs @Timeout + $BootVer = Get-CSRegistryValue -Hive HKLM -SubKey 'SYSTEM\CurrentControlSet\Control\BootVerificationProgram' -ValueName 'ImagePath' @CommonArgs if ($BootVer) { $BootVer | New-AutoRunsEntry -Hive $BootVer.Hive -SubKey "$($BootVer.SubKey)\ImagePath" } foreach ($SID in $HKUSIDs) { - $Scrnsave = Get-CSRegistryValue -Hive HKU -SubKey "$SID\SOFTWARE\Policies\Microsoft\Windows\Control Panel\Desktop" -ValueName 'Scrnsave.exe' @CommonArgs @Timeout + $Scrnsave = Get-CSRegistryValue -Hive HKU -SubKey "$SID\SOFTWARE\Policies\Microsoft\Windows\Control Panel\Desktop" -ValueName 'Scrnsave.exe' @CommonArgs if ($Scrnsave) { $Scrnsave | New-AutoRunsEntry -Category $Category } - $Scrnsave = Get-CSRegistryValue -Hive HKU -SubKey "$SID\Control Panel\Desktop" -ValueName 'Scrnsave.exe' @CommonArgs @Timeout + $Scrnsave = Get-CSRegistryValue -Hive HKU -SubKey "$SID\Control Panel\Desktop" -ValueName 'Scrnsave.exe' @CommonArgs if ($Scrnsave) { $Scrnsave | New-AutoRunsEntry -Category $Category } } } @@ -525,14 +510,6 @@ Get-CSStartMenuEntry returns file information for all files present (excluding d Specifies the CIM session to use for this cmdlet. Enter a variable that contains the CIM session or a command that creates or gets the CIM session, such as the New-CimSession or Get-CimSession cmdlets. For more information, see about_CimSessions. -.PARAMETER OperationTimeoutSec - -Specifies the amount of time that the cmdlet waits for a response from the computer. - -By default, the value of this parameter is 0, which means that the cmdlet uses the default timeout value for the server. - -If the OperationTimeoutSec parameter is set to a value less than the robust connection retry timeout of 3 minutes, network failures that last more than the value of the OperationTimeoutSec parameter are not recoverable, because the operation on the server times out before the client can reconnect. - .EXAMPLE Get-CSStartMenuEntry @@ -562,11 +539,7 @@ If a shortcut is present in the start menu, an instance of a Win32_ShortcutFile [Alias('Session')] [ValidateNotNullOrEmpty()] [Microsoft.Management.Infrastructure.CimSession[]] - $CimSession, - - [UInt32] - [Alias('OT')] - $OperationTimeoutSec + $CimSession ) BEGIN { @@ -579,9 +552,6 @@ If a shortcut is present in the start menu, an instance of a Win32_ShortcutFile } $CurrentCIMSession = 0 - - $Timeout = @{} - if ($PSBoundParameters['OperationTimeoutSec']) { $Timeout['OperationTimeoutSec'] = $OperationTimeoutSec } } PROCESS { @@ -597,14 +567,14 @@ If a shortcut is present in the start menu, an instance of a Win32_ShortcutFile if ($Session.Id) { $CommonArgs['CimSession'] = $Session } - Get-CSShellFolderPath -SystemFolder -FolderName 'Common Startup' @CommonArgs @Timeout | ForEach-Object { - Get-CSDirectoryListing -DirectoryPath $_.ValueContent -File @CommonArgs @Timeout | Where-Object { + Get-CSShellFolderPath -SystemFolder -FolderName 'Common Startup' @CommonArgs | ForEach-Object { + Get-CSDirectoryListing -DirectoryPath $_.ValueContent -File @CommonArgs | Where-Object { $_.FileName -ne 'desktop' -and $_.Extension -ne 'ini' } } - Get-CSShellFolderPath -UserFolder -FolderName 'Startup' @CommonArgs @Timeout | ForEach-Object { - Get-CSDirectoryListing -DirectoryPath $_.ValueContent -File @CommonArgs @Timeout | Where-Object { + Get-CSShellFolderPath -UserFolder -FolderName 'Startup' @CommonArgs | ForEach-Object { + Get-CSDirectoryListing -DirectoryPath $_.ValueContent -File @CommonArgs | Where-Object { $_.FileName -ne 'desktop' -and $_.Extension -ne 'ini' } } @@ -629,14 +599,6 @@ Get-CSWmiPersistence lists all registered __FilterToConsumerBinding objects and Specifies the CIM session to use for this cmdlet. Enter a variable that contains the CIM session or a command that creates or gets the CIM session, such as the New-CimSession or Get-CimSession cmdlets. For more information, see about_CimSessions. -.PARAMETER OperationTimeoutSec - -Specifies the amount of time that the cmdlet waits for a response from the computer. - -By default, the value of this parameter is 0, which means that the cmdlet uses the default timeout value for the server. - -If the OperationTimeoutSec parameter is set to a value less than the robust connection retry timeout of 3 minutes, network failures that last more than the value of the OperationTimeoutSec parameter are not recoverable, because the operation on the server times out before the client can reconnect. - .EXAMPLE Get-CSWmiPersistence @@ -660,11 +622,7 @@ Get-CSWmiPersistence only returns output when __FilterToConsumerBinding instance [Alias('Session')] [ValidateNotNullOrEmpty()] [Microsoft.Management.Infrastructure.CimSession[]] - $CimSession, - - [UInt32] - [Alias('OT')] - $OperationTimeoutSec + $CimSession ) BEGIN { @@ -678,9 +636,6 @@ Get-CSWmiPersistence only returns output when __FilterToConsumerBinding instance } $Current = 0 - - $Timeout = @{} - if ($PSBoundParameters['OperationTimeoutSec']) { $Timeout['OperationTimeoutSec'] = $OperationTimeoutSec } } PROCESS { @@ -694,13 +649,13 @@ Get-CSWmiPersistence only returns output when __FilterToConsumerBinding instance Write-Verbose "[$($Session.ComputerName)] Retrieving __FilterToConsumerBinding instance." - Get-CimInstance -Namespace root/subscription -ClassName __FilterToConsumerBinding @CommonArgs @Timeout | ForEach-Object { + Get-CimInstance -Namespace root/subscription -ClassName __FilterToConsumerBinding @CommonArgs | ForEach-Object { Write-Verbose "[$($Session.ComputerName)] Correlating referenced __EventFilter instance." - $Filter = Get-CimInstance -Namespace root/subscription -ClassName __EventFilter -Filter "Name=`"$($_.Filter.Name)`"" @CommonArgs @Timeout + $Filter = Get-CimInstance -Namespace root/subscription -ClassName __EventFilter -Filter "Name=`"$($_.Filter.Name)`"" @CommonArgs $ConsumerClass = $_.Consumer.PSObject.TypeNames[0].Split('/')[-1] Write-Verbose "[$($Session.ComputerName)] Correlating referenced __EventConsumer instance." - $Consumer = Get-CimInstance -Namespace root/subscription -ClassName $ConsumerClass -Filter "Name=`"$($_.Consumer.Name)`"" @CommonArgs @Timeout + $Consumer = Get-CimInstance -Namespace root/subscription -ClassName $ConsumerClass -Filter "Name=`"$($_.Consumer.Name)`"" @CommonArgs $ObjectProperties = [Ordered] @{ PSTypeName = 'CimSweep.WmiPersistence' diff --git a/CimSweep/Defense/Bitlocker.ps1 b/CimSweep/Defense/Bitlocker.ps1 index 9bffa26..18fbb6f 100644 --- a/CimSweep/Defense/Bitlocker.ps1 +++ b/CimSweep/Defense/Bitlocker.ps1 @@ -20,14 +20,6 @@ Specifies the drive letter for the volume you want to obtain key Bitlocker key m Specifies the CIM session to use for this cmdlet. Enter a variable that contains the CIM session or a command that creates or gets the CIM session, such as the New-CimSession or Get-CimSession cmdlets. For more information, see about_CimSessions. -.PARAMETER OperationTimeoutSec - -Specifies the amount of time that the cmdlet waits for a response from the computer. - -By default, the value of this parameter is 0, which means that the cmdlet uses the default timeout value for the server. - -If the OperationTimeoutSec parameter is set to a value less than the robust connection retry timeout of 3 minutes, network failures that last more than the value of the OperationTimeoutSec parameter are not recoverable, because the operation on the server times out before the client can reconnect. - .EXAMPLE Get-CSBitlockerKeyProtector @@ -57,11 +49,7 @@ Outputs objects representing Bitlocker volume key material. [Alias('Session')] [ValidateNotNullOrEmpty()] [Microsoft.Management.Infrastructure.CimSession[]] - $CimSession, - - [UInt32] - [Alias('OT')] - $OperationTimeoutSec + $CimSession ) BEGIN { diff --git a/CimSweep/Defense/SuspiciousFiles.ps1 b/CimSweep/Defense/SuspiciousFiles.ps1 index a9df314..150582f 100644 --- a/CimSweep/Defense/SuspiciousFiles.ps1 +++ b/CimSweep/Defense/SuspiciousFiles.ps1 @@ -15,14 +15,6 @@ The ability to remotely query scheduled tasks was not introduced until Windows 8 Specifies the CIM session to use for this cmdlet. Enter a variable that contains the CIM session or a command that creates or gets the CIM session, such as the New-CimSession or Get-CimSession cmdlets. For more information, see about_CimSessions. -.PARAMETER OperationTimeoutSec - -Specifies the amount of time that the cmdlet waits for a response from the computer. - -By default, the value of this parameter is 0, which means that the cmdlet uses the default timeout value for the server. - -If the OperationTimeoutSec parameter is set to a value less than the robust connection retry timeout of 3 minutes, network failures that last more than the value of the OperationTimeoutSec parameter are not recoverable, because the operation on the server times out before the client can reconnect. - .EXAMPLE Get-CSScheduledTaskFile @@ -48,11 +40,7 @@ Outputs CIM_DataFile instances representing task XML files. [Alias('Session')] [ValidateNotNullOrEmpty()] [Microsoft.Management.Infrastructure.CimSession[]] - $CimSession, - - [UInt32] - [Alias('OT')] - $OperationTimeoutSec + $CimSession ) BEGIN { @@ -65,9 +53,6 @@ Outputs CIM_DataFile instances representing task XML files. } $CurrentCIMSession = 0 - - $Timeout = @{} - if ($PSBoundParameters['OperationTimeoutSec']) { $Timeout['OperationTimeoutSec'] = $OperationTimeoutSec } } PROCESS { @@ -83,7 +68,7 @@ Outputs CIM_DataFile instances representing task XML files. if ($Session.Id) { $CommonArgs['CimSession'] = $Session } - $OSInfo = Get-CimInstance -ClassName Win32_OperatingSystem -Property SystemDirectory, WindowsDirectory @CommonArgs @Timeout + $OSInfo = Get-CimInstance -ClassName Win32_OperatingSystem -Property SystemDirectory, WindowsDirectory @CommonArgs if ($OSInfo.SystemDirectory -and $OSInfo.WindowsDirectory) { # %SystemRoot%\System32\Tasks @@ -98,14 +83,14 @@ Outputs CIM_DataFile instances representing task XML files. Write-Progress -Id 2 -ParentId 1 -Activity "Current directory:" -Status $_ # List tasks in root directory - Get-CSDirectoryListing -DirectoryPath $_ -File @CommonArgs @Timeout + Get-CSDirectoryListing -DirectoryPath $_ -File @CommonArgs # Start by only retrieving directory info recursively. This is a performance enhancement - Get-CSDirectoryListing -DirectoryPath $_ -Recurse -Directory -DoNotDetectRecursiveDirs @CommonArgs @Timeout | ForEach-Object { + Get-CSDirectoryListing -DirectoryPath $_ -Recurse -Directory -DoNotDetectRecursiveDirs @CommonArgs | ForEach-Object { Write-Progress -Id 2 -ParentId 1 -Activity "Current directory:" -Status ($_.Name) # Get task file information for each subdirectory - $_ | Get-CSDirectoryListing -File @CommonArgs @Timeout + $_ | Get-CSDirectoryListing -File @CommonArgs } } } else { @@ -270,23 +255,23 @@ Outputs a list of registry values representing shell folder paths. # Get a precise registry value if a specific folder is specified. This is a performance enhancement. if ($PSBoundParameters['FolderName']) { if (($PSCmdlet.ParameterSetName -eq 'System') -or ($PSCmdlet.ParameterSetName -eq 'Default')) { - Get-CSRegistryValue -Hive HKLM -SubKey $ShellFolders -ValueName $FolderName -ValueType REG_SZ @CommonArgs @Timeout | + Get-CSRegistryValue -Hive HKLM -SubKey $ShellFolders -ValueName $FolderName -ValueType REG_SZ @CommonArgs | Where-Object { $_.ValueContent } } if (($PSCmdlet.ParameterSetName -eq 'User') -or ($PSCmdlet.ParameterSetName -eq 'Default')) { # Get the SIDS for each user in the registry - $HKUSIDs = Get-HKUSID @CommonArgs @Timeout + $HKUSIDs = Get-HKUSID @CommonArgs # Iterate over each local user hive foreach ($SID in $HKUSIDs) { - Get-CSRegistryValue -Hive HKU -SubKey "$SID\$ShellFolders" -ValueName $FolderName -ValueType REG_SZ @CommonArgs @Timeout | + Get-CSRegistryValue -Hive HKU -SubKey "$SID\$ShellFolders" -ValueName $FolderName -ValueType REG_SZ @CommonArgs | Where-Object { $_.ValueContent } } } } else { # Otherwise, retrieve all shell folders if (($PSCmdlet.ParameterSetName -eq 'System') -or ($PSCmdlet.ParameterSetName -eq 'Default')) { - Get-CSRegistryValue -Hive HKLM -SubKey $ShellFolders -ValueNameOnly @CommonArgs @Timeout | + Get-CSRegistryValue -Hive HKLM -SubKey $ShellFolders -ValueNameOnly @CommonArgs | Where-Object { -not $_.ValueName.StartsWith('!') -and -not $_.ValueName.StartsWith('{') } | Get-CSRegistryValue } @@ -297,7 +282,7 @@ Outputs a list of registry values representing shell folder paths. # Iterate over each local user hive foreach ($SID in $HKUSIDs) { - Get-CSRegistryValue -Hive HKU -SubKey "$SID\$ShellFolders" -ValueNameOnly @CommonArgs @Timeout | + Get-CSRegistryValue -Hive HKU -SubKey "$SID\$ShellFolders" -ValueNameOnly @CommonArgs | Where-Object { -not $_.ValueName.StartsWith('!') -and -not $_.ValueName.StartsWith('{') } | Get-CSRegistryValue } @@ -443,7 +428,7 @@ Outputs CIM_DataFile instances of files present in the specified temp directory if (($PSCmdlet.ParameterSetName -eq 'System') -or ($PSCmdlet.ParameterSetName -eq 'Default')) { # Get system temp path from the registry - $SystemTempPath = Get-CSEnvironmentVariable -SystemVariable -VariableName TEMP @CommonArgs @Timeout + $SystemTempPath = Get-CSEnvironmentVariable -SystemVariable -VariableName TEMP @CommonArgs if ($SystemTempPath.VariableValue) { Write-Verbose "[$ComputerName] User temp directory: $($SystemTempPath.VariableValue)" @@ -451,13 +436,13 @@ Outputs CIM_DataFile instances of files present in the specified temp directory Write-Progress -Id 2 -ParentId 1 -Activity "Current directory:" -Status $SystemTempPath.VariableValue # Display files in the root temp dir - Get-CSDirectoryListing -DirectoryPath $SystemTempPath.VariableValue -File @TargetExtensions @CommonArgs @Timeout + Get-CSDirectoryListing -DirectoryPath $SystemTempPath.VariableValue -File @TargetExtensions @CommonArgs if (-not $PSBoundParameters['DoNotRecurse']) { - Get-CSDirectoryListing -DirectoryPath $SystemTempPath.VariableValue -Directory -Recurse @CommonArgs @Timeout | ForEach-Object { + Get-CSDirectoryListing -DirectoryPath $SystemTempPath.VariableValue -Directory -Recurse @CommonArgs | ForEach-Object { Write-Progress -Id 2 -ParentId 1 -Activity "Current directory:" -Status ($_.Name) - $_ | Get-CSDirectoryListing -File @TargetExtensions @Timeout + $_ | Get-CSDirectoryListing -File @TargetExtensions } } } else { @@ -467,8 +452,8 @@ Outputs CIM_DataFile instances of files present in the specified temp directory if (($PSCmdlet.ParameterSetName -eq 'User') -or ($PSCmdlet.ParameterSetName -eq 'Default')) { # Get user %USERPROFILE% and validate the end of %TEMP%. The root path of %TEMP% is not often not resolved properly. - $UserProfiles = Get-CSEnvironmentVariable -UserVariable -VariableName USERPROFILE @CommonArgs @Timeout - $TempVars = Get-CSEnvironmentVariable -UserVariable -VariableName TEMP @CommonArgs @Timeout + $UserProfiles = Get-CSEnvironmentVariable -UserVariable -VariableName USERPROFILE @CommonArgs + $TempVars = Get-CSEnvironmentVariable -UserVariable -VariableName TEMP @CommonArgs foreach ($UserProfile in $UserProfiles) { $TempVars | Where-Object { $_.User -eq $UserProfile.User } | ForEach-Object { @@ -493,13 +478,13 @@ Outputs CIM_DataFile instances of files present in the specified temp directory Write-Progress -Id 2 -ParentId 1 -Activity "Current directory:" -Status $FullTempPath # Display files in the root temp dir - Get-CSDirectoryListing -DirectoryPath $FullTempPath -File @TargetExtensions @CommonArgs @Timeout + Get-CSDirectoryListing -DirectoryPath $FullTempPath -File @TargetExtensions @CommonArgs if (-not $PSBoundParameters['DoNotRecurse']) { - Get-CSDirectoryListing -DirectoryPath $FullTempPath -Directory -Recurse @CommonArgs @Timeout | ForEach-Object { + Get-CSDirectoryListing -DirectoryPath $FullTempPath -Directory -Recurse @CommonArgs | ForEach-Object { Write-Progress -Id 2 -ParentId 1 -Activity "Current directory:" -Status ($_.Name) - $_ | Get-CSDirectoryListing -File @TargetExtensions @Timeout + $_ | Get-CSDirectoryListing -File @TargetExtensions } } } @@ -614,7 +599,7 @@ Outputs CIM_DataFile instances of files present in low-integrity level directori if ($Session.Id) { $CommonArgs['CimSession'] = $Session } - Get-CSEnvironmentVariable -UserVariable -VariableName LOCALAPPDATA @CommonArgs @Timeout | ForEach-Object { + Get-CSEnvironmentVariable -UserVariable -VariableName LOCALAPPDATA @CommonArgs | ForEach-Object { Write-Verbose "[$ComputerName] LocalAppData path: $($_.VariableValue)" if ($_.VariableValue) { @@ -623,13 +608,13 @@ Outputs CIM_DataFile instances of files present in low-integrity level directori Write-Progress -Id 2 -ParentId 1 -Activity "Current directory:" -Status $LocalLowPath # List all files in the root low IL dir - Get-CSDirectoryListing -DirectoryPath $LocalLowPath -File @TargetExtensions @CommonArgs @Timeout + Get-CSDirectoryListing -DirectoryPath $LocalLowPath -File @TargetExtensions @CommonArgs if (-not $PSBoundParameters['DoNotRecurse']) { - Get-CSDirectoryListing -DirectoryPath $LocalLowPath -Recurse -Directory @CommonArgs @Timeout | ForEach-Object { + Get-CSDirectoryListing -DirectoryPath $LocalLowPath -Recurse -Directory @CommonArgs | ForEach-Object { Write-Progress -Id 2 -ParentId 1 -Activity "Current directory:" -Status ($_.Name) - $_ | Get-CSDirectoryListing -File @TargetExtensions @Timeout + $_ | Get-CSDirectoryListing -File @TargetExtensions } } } diff --git a/CimSweep/Defense/SuspiciousURLs.ps1 b/CimSweep/Defense/SuspiciousURLs.ps1 index ca9af2d..044fe27 100644 --- a/CimSweep/Defense/SuspiciousURLs.ps1 +++ b/CimSweep/Defense/SuspiciousURLs.ps1 @@ -15,14 +15,6 @@ Get-CSTypedURL retrieves URLs that were typed into the Internet Explorer URL bar Specifies the CIM session to use for this cmdlet. Enter a variable that contains the CIM session or a command that creates or gets the CIM session, such as the New-CimSession or Get-CimSession cmdlets. For more information, see about_CimSessions. -.PARAMETER OperationTimeoutSec - -Specifies the amount of time that the cmdlet waits for a response from the computer. - -By default, the value of this parameter is 0, which means that the cmdlet uses the default timeout value for the server. - -If the OperationTimeoutSec parameter is set to a value less than the robust connection retry timeout of 3 minutes, network failures that last more than the value of the OperationTimeoutSec parameter are not recoverable, because the operation on the server times out before the client can reconnect. - .EXAMPLE Get-CSTypedURL @@ -48,11 +40,7 @@ Outputs the registry values consisting of typed IE URLs. [Alias('Session')] [ValidateNotNullOrEmpty()] [Microsoft.Management.Infrastructure.CimSession[]] - $CimSession, - - [UInt32] - [Alias('OT')] - $OperationTimeoutSec + $CimSession ) BEGIN { @@ -65,9 +53,6 @@ Outputs the registry values consisting of typed IE URLs. } $CurrentCIMSession = 0 - - $Timeout = @{} - if ($PSBoundParameters['OperationTimeoutSec']) { $Timeout['OperationTimeoutSec'] = $OperationTimeoutSec } } PROCESS { @@ -90,7 +75,7 @@ Outputs the registry values consisting of typed IE URLs. # Iterate over each local user hive foreach ($SID in $HKUSIDs) { - Get-CSRegistryValue -Hive HKU -SubKey "$SID\$TypedURLs" @CommonArgs @Timeout + Get-CSRegistryValue -Hive HKU -SubKey "$SID\$TypedURLs" @CommonArgs } } } diff --git a/CimSweep/Offense/ACLAudits.ps1 b/CimSweep/Offense/ACLAudits.ps1 index a960da4..c93be08 100644 --- a/CimSweep/Offense/ACLAudits.ps1 +++ b/CimSweep/Offense/ACLAudits.ps1 @@ -19,14 +19,6 @@ Specifies that driver file permissions should be queried in addition to user-mod Specifies the CIM session to use for this cmdlet. Enter a variable that contains the CIM session or a command that creates or gets the CIM session, such as the New-CimSession or Get-CimSession cmdlets. For more information, see about_CimSessions. -.PARAMETER OperationTimeoutSec - -Specifies the amount of time that the cmdlet waits for a response from the computer. - -By default, the value of this parameter is 0, which means that the cmdlet uses the default timeout value for the server. - -If the OperationTimeoutSec parameter is set to a value less than the robust connection retry timeout of 3 minutes, network failures that last more than the value of the OperationTimeoutSec parameter are not recoverable, because the operation on the server times out before the client can reconnect. - .EXAMPLE Get-CSVulnerableServicePermission @@ -55,11 +47,7 @@ Service ACL sweep across a large amount of hosts will take a long time. [Alias('Session')] [ValidateNotNullOrEmpty()] [Microsoft.Management.Infrastructure.CimSession[]] - $CimSession, - - [UInt32] - [Alias('OT')] - $OperationTimeoutSec + $CimSession ) BEGIN { @@ -76,9 +64,6 @@ Service ACL sweep across a large amount of hosts will take a long time. if (-not $IncludeDrivers) { $UserModeServices['UserModeServices'] = $True } - - $Timeout = @{} - if ($PSBoundParameters['OperationTimeoutSec']) { $Timeout['OperationTimeoutSec'] = $OperationTimeoutSec } } PROCESS { @@ -96,7 +81,7 @@ Service ACL sweep across a large amount of hosts will take a long time. $UserGrouping = @{} - Get-CSService -IncludeAcl -IncludeFileInfo @UserModeServices @CommonArgs @Timeout | ForEach-Object { + Get-CSService -IncludeAcl -IncludeFileInfo @UserModeServices @CommonArgs | ForEach-Object { $ServiceName = $_.Name Write-Progress -Id 2 -ParentId 1 -Activity " Current service:" -Status $ServiceName diff --git a/CimSweep/Offense/AntiVirusInfo.ps1 b/CimSweep/Offense/AntiVirusInfo.ps1 index 0255fd7..1f71532 100644 --- a/CimSweep/Offense/AntiVirusInfo.ps1 +++ b/CimSweep/Offense/AntiVirusInfo.ps1 @@ -16,10 +16,6 @@ Get-CSAVInfo uses the AntiVirusProduct WMI class to enumerate Anti Virus on a lo Specifies the CIM session to use for this cmdlet. Enter a variable that contains the CIM session or a command that creates or gets the CIM session, such as the New-CimSession or Get-CimSession cmdlets. For more information, see about_CimSessions. -.PARAMETER OperationTimeoutSec - -Specifies the amount of time that the cmdlet waits for a response from the computer. - .EXAMPLE Get-CimAVInfo @@ -42,11 +38,7 @@ Outputs custom objects representing the current AV configuration. [Alias('Session')] [ValidateNotNullOrEmpty()] [Microsoft.Management.Infrastructure.CimSession[]] - $CimSession, - - [UInt32] - [Alias('OT')] - $OperationTimeoutSec + $CimSession ) @@ -56,9 +48,6 @@ Outputs custom objects representing the current AV configuration. { $CimSession = '' } - - $Timeout = @{} - if ($PSBoundParameters['OperationTimeoutSec']) { $Timeout['OperationTimeoutSec'] = $OperationTimeoutSec } } PROCESS @@ -76,11 +65,11 @@ Outputs custom objects representing the current AV configuration. if ($Session.Id) {$CommonArgs['CimSession'] = $Session} #Determine if the namespace exists - if (Get-CimInstance -Namespace root -ClassName __NAMESPACE -Filter 'Name="SecurityCenter2"' @CommonArgs @Timeout) + if (Get-CimInstance -Namespace root -ClassName __NAMESPACE -Filter 'Name="SecurityCenter2"' @CommonArgs) { $InstanceArgs['Namespace'] = 'root/SecurityCenter2' } - elseif (Get-CimInstance -Namespace root -ClassName __NAMESPACE -Filter 'Name="SecurityCenter"' @CommonArgs @Timeout) + elseif (Get-CimInstance -Namespace root -ClassName __NAMESPACE -Filter 'Name="SecurityCenter"' @CommonArgs) { $InstanceArgs['Namespace'] = 'root/SecurityCenter' } @@ -89,7 +78,7 @@ Outputs custom objects representing the current AV configuration. break } - $AV = Get-CimInstance @InstanceArgs @CommonArgs @Timeout + $AV = Get-CimInstance @InstanceArgs @CommonArgs if ($InstanceArgs['NameSpace'] -eq 'root/SecurityCenter2') { @@ -167,7 +156,7 @@ Outputs custom objects representing the current AV configuration. { $ExclusionInfo = [PSCustomObject] @{} $DefenderPaths.GetEnumerator() | ForEach-Object { - $ExclusionInfo | Add-Member -NotePropertyName $_.Key -NotePropertyValue $(Get-CSRegistryValue -Hive HKLM -SubKey $($_.Value) @CommonArgs @Timeout).ValueName + $ExclusionInfo | Add-Member -NotePropertyName $_.Key -NotePropertyValue $(Get-CSRegistryValue -Hive HKLM -SubKey $($_.Value) @CommonArgs).ValueName } } @@ -175,7 +164,7 @@ Outputs custom objects representing the current AV configuration. { $ExclusionInfo = [PSCustomObject] @{} $McAfeePaths.GetEnumerator() | ForEach-Object { - $ExclusionInfo | Add-Member -NotePropertyName $_.Key -NotePropertyValue $(Get-CSRegistryValue -Hive HKLM -SubKey $($_.Value) @CommonArgs @Timeout).ValueName + $ExclusionInfo | Add-Member -NotePropertyName $_.Key -NotePropertyValue $(Get-CSRegistryValue -Hive HKLM -SubKey $($_.Value) @CommonArgs).ValueName } } diff --git a/CimSweep/Offense/ProxyConfig.ps1 b/CimSweep/Offense/ProxyConfig.ps1 index 7271ece..95eed8c 100644 --- a/CimSweep/Offense/ProxyConfig.ps1 +++ b/CimSweep/Offense/ProxyConfig.ps1 @@ -18,10 +18,6 @@ Specifies the user name to enumerate proxy settings for. Specifies the CIM session to use for this cmdlet. Enter a variable that contains the CIM session or a command that creates or gets the CIM session, such as the New-CimSession or Get-CimSession cmdlets. For more information, see about_CimSessions. -.PARAMETER OperationTimeoutSec - -Specifies the amount of time that the cmdlet waits for a response from the computer. - .EXAMPLE Get-CSProxyConfig -UserName bob @@ -48,11 +44,7 @@ CimSweep.ProxyConfig [Alias('Session')] [ValidateNotNullOrEmpty()] [Microsoft.Management.Infrastructure.CimSession[]] - $CimSession, - - [UInt32] - [Alias('OT')] - $OperationTimeoutSec + $CimSession ) BEGIN @@ -87,13 +79,13 @@ CimSweep.ProxyConfig if($PSBoundParameters['UserName']) { $InstanceArgs['Filter'] = "Name=`'$UserName`'" - $SID = (Get-CimInstance @InstanceArgs @CommonArgs @Timeout).SID + $SID = (Get-CimInstance @InstanceArgs @CommonArgs).SID $Hive = 'HKU' $SubKey = "$SID\SOFTWARE\Microsoft\Windows\CurrentVersion\Internet Settings\Connections" } - $ProxyConfig = Get-CSRegistryValue -Hive $Hive -SubKey $SubKey -ValueName 'DefaultConnectionSettings' @CommonArgs @Timeout + $ProxyConfig = Get-CSRegistryValue -Hive $Hive -SubKey $SubKey -ValueName 'DefaultConnectionSettings' @CommonArgs if (-not $ProxyConfig) { break } @@ -116,7 +108,7 @@ CimSweep.ProxyConfig $SubKey = $SubKey.TrimEnd('Connections') $InternetSettings = [PSCustomObject] @{} - Get-CSRegistryValue -Hive $Hive -SubKey $SubKey @CommonArgs @Timeout | ForEach-Object { + Get-CSRegistryValue -Hive $Hive -SubKey $SubKey @CommonArgs | ForEach-Object { $InternetSettings | Add-Member -NotePropertyName $_.ValueName -NotePropertyValue $_.ValueContent } diff --git a/CimSweep/Tests/Core.CimSweep.Tests.ps1 b/CimSweep/Tests/Core.CimSweep.Tests.ps1 index 4b9c77c..b7513bf 100644 --- a/CimSweep/Tests/Core.CimSweep.Tests.ps1 +++ b/CimSweep/Tests/Core.CimSweep.Tests.ps1 @@ -39,11 +39,6 @@ Describe 'Get-CSRegistryKey' { { Get-CSRegistryKey -Hive HKLM -CimSession $TestCimSession1 } | Should Not BeNullOrEmpty { Get-CSRegistryKey -Hive HKLM -CimSession $TestSessionArray } | Should Not BeNullOrEmpty } - - It 'should accept -OperationTimeoutSec' { - { Get-CSRegistryKey -Hive HKLM -OperationTimeoutSec 3 } | Should Not Throw - { Get-CSRegistryKey -Hive HKLM -OperationTimeoutSec 3 -CimSession $TestCimSession1 } | Should Not Throw - } } Context 'expected behavior' { @@ -129,11 +124,6 @@ Describe 'Get-CSRegistryValue' { { Get-CSRegistryValue -Hive HKLM -SubKey $CurrentVersionPath -CimSession $TestCimSession1 } | Should Not BeNullOrEmpty { Get-CSRegistryValue -Hive HKLM -SubKey $CurrentVersionPath -CimSession $TestSessionArray } | Should Not BeNullOrEmpty } - - It 'should accept -OperationTimeoutSec' { - { Get-CSRegistryValue -Hive HKLM -SubKey $CurrentVersionPath -OperationTimeoutSec 3 } | Should Not Throw - { Get-CSRegistryValue -Hive HKLM -SubKey $CurrentVersionPath -OperationTimeoutSec 3 -CimSession $TestCimSession1 } | Should Not Throw - } } Context 'expected behavior' { @@ -319,19 +309,6 @@ Describe 'Get-CSEventLog' { $Result.LogName | Should Not BeNullOrEmpty $Result.PSComputerName | Should BeExactly 'localhost' } - - It 'should return output and accept -OperationTimeoutSec' { - $Result = Get-CSEventLog -OperationTimeoutSec 3 | Select -First 1 - - $Result.LogName | Should Not BeNullOrEmpty - } - - It 'should return output with CIM sessions and accept -OperationTimeoutSec' { - $Result = Get-CSEventLog -CimSession $TestSessionArray -OperationTimeoutSec 3 | Select -First 1 - - $Result.LogName | Should Not BeNullOrEmpty - $Result.PSComputerName | Should BeExactly 'localhost' - } } Describe 'Get-CSEventLogEntry' { @@ -466,14 +443,6 @@ Describe 'Get-CSMountedVolumeDriveLetter' { $Drive.DirectoryPath | Should Match "^$($Drive.DriveLetter):\\`$" $Drive.PSComputerName | Should BeExactly 'localhost' } - - It 'should accept -OperationTimeoutSec' { - $Drive = Get-CSMountedVolumeDriveLetter -OperationTimeoutSec 3 | Select-Object -First 1 - - $Drive | Should Not BeNullOrEmpty - $Drive.DriveLetter | Should Match '^[A-Z]$' - $Drive.DirectoryPath | Should Match "^$($Drive.DriveLetter):\\`$" - } } Describe 'Get-CSDirectoryListing' { @@ -1101,11 +1070,6 @@ Describe 'Get-CSWmiNamespace' { { Get-CSWmiNamespace -CimSession $TestCimSession1 -ErrorAction Stop } | Should Not BeNullOrEmpty { Get-CSWmiNamespace -CimSession $TestSessionArray -ErrorAction Stop } | Should Not BeNullOrEmpty } - - It 'should accept -OperationTimeoutSec' { - { Get-CSWmiNamespace -OperationTimeoutSec 3 -ErrorAction Stop } | Should Not Throw - { Get-CSWmiNamespace -OperationTimeoutSec 3 -CimSession $TestCimSession1 -ErrorAction Stop } | Should Not Throw - } } Context 'expected behavior' { diff --git a/CimSweep/Tests/Module.Tests.ps1 b/CimSweep/Tests/Module.Tests.ps1 index 91592b4..b8e3985 100644 --- a/CimSweep/Tests/Module.Tests.ps1 +++ b/CimSweep/Tests/Module.Tests.ps1 @@ -32,13 +32,6 @@ Describe 'Module-wide tests' -Tags 'Module' { $CimSessionParam.Name.Extent.Text | Should BeExactly '$CimSession' $CimSessionParam.StaticType.FullName | Should BeExactly 'Microsoft.Management.Infrastructure.CimSession[]' } - - It 'should have a -OperationTimeoutSec parameter with proper capitalization and is of type UInt32' { - $CimSessionParam = $AST.ParamBlock.Parameters | Where-Object { $_.Name.Extent.Text -eq '$OperationTimeoutSec' } - $CimSessionParam | Should Not BeNullOrEmpty - $CimSessionParam.Name.Extent.Text | Should BeExactly '$OperationTimeoutSec' - $CimSessionParam.StaticType.FullName | Should BeExactly 'System.UInt32' - } } Context "Required exported command naming scheme for $Function" { @@ -67,10 +60,10 @@ Describe 'Module-wide tests' -Tags 'Module' { } # Get the parameters declared in the Comment Based Help - $HelpParameters = $Help.Parameters.Parameter + $HelpParameters = @($Help.Parameters.Parameter) # Get the parameters declared in the AST PARAM() Block - $ASTParameters = $AST.ParamBlock.Parameters.Name.Variablepath.Userpath + $ASTParameters = @($AST.ParamBlock.Parameters.Name.Variablepath.Userpath) It 'should contain a matching number of .PARAMETER blocks for all defined parameters' { $NamedArgs = try { $AST.ParamBlock.Attributes.NamedArguments } catch {} diff --git a/README.md b/README.md index 98ed5ea..57f63b5 100644 --- a/README.md +++ b/README.md @@ -93,18 +93,17 @@ All of the following requirements will have an accompanying Pester test to ensur 1. All functions must have an OutputType attribute and an accompanying .OUTPUTS block in comment-based help. It is important to know the types of objects that a function outputs including with custom PowerShell objects. You can apply a type name to custom objects by including a PSTypeName property to each object. Custom object type names must start with CimSweep - e.g. CimSweep.RegistryKey. 2. All functions must support a -CimSession parameter along with respective .PARAMETER documentation. -3. All functions must support a -OperationTimeoutSec parameter along with respective .PARAMETER documentation. -4. All function names must have a "CS" noun prefix. -5. All functions must contain a .SYNOPSIS help block. -6. All functions must contain an author name in .SYNOPSIS. -7. All functions must contain a BSD license clause in .SYNOPSIS. -8. All functions must contain a .DESCRIPTION help block. -9. All functions must contain a .PARAMETER block for each defined parameter. -10. All functions must contain at lease one .EXAMPLE block. +3. All function names must have a "CS" noun prefix. +4. All functions must contain a .SYNOPSIS help block. +5. All functions must contain an author name in .SYNOPSIS. +6. All functions must contain a BSD license clause in .SYNOPSIS. +7. All functions must contain a .DESCRIPTION help block. +8. All functions must contain a .PARAMETER block for each defined parameter. +9. All functions must contain at lease one .EXAMPLE block. #### Optional design considerations. 1. Your function should include a Pester test!!! How else can you be sure it works as designed and that it will be resiliant to refactoring? Without a Pester test, you'll just be left guessing as to whether or not your code will be stable in production. -2. All functions should utilize Write-Progress. A progress bar can come in very handy when running a sweep across 1000 systems. +2. All non-core functions should utilize Write-Progress. A progress bar can come in very handy when running a sweep across 1000 systems. 3. All error or verbose messages should include the computer name for the local or remote session. This is helpful when diagnosing issues on a large number of remote sessions. #### Additional design considerations From 1033c51148b350543f8efaab20cc42a6168301bb Mon Sep 17 00:00:00 2001 From: Matt Graeber Date: Wed, 2 Nov 2016 07:57:28 -0700 Subject: [PATCH 08/15] Allow some arguments to accept empty strings The following arguments can now accept empty strings. Get-CSService: * -DisplayName * -PathName * -Description Get-CSProcess: * -CommandLine * -ExecutablePath --- CimSweep/Core/CoreFunctions.ps1 | 50 ++++++++++++++++++++++++++------- 1 file changed, 40 insertions(+), 10 deletions(-) diff --git a/CimSweep/Core/CoreFunctions.ps1 b/CimSweep/Core/CoreFunctions.ps1 index ed4630f..fa288d3 100644 --- a/CimSweep/Core/CoreFunctions.ps1 +++ b/CimSweep/Core/CoreFunctions.ps1 @@ -1558,7 +1558,7 @@ Outputs Win32_Service or Win32_SystemDriver instances both of which derive from [Parameter(ParameterSetName='DefaultOutput')] [Parameter(ParameterSetName='RestrictOutput')] [String] - [ValidateNotNullOrEmpty()] + [ValidateNotNull()] $DisplayName, [Parameter(ParameterSetName='DefaultOutput')] @@ -1582,13 +1582,13 @@ Outputs Win32_Service or Win32_SystemDriver instances both of which derive from [Parameter(ParameterSetName='DefaultOutput')] [Parameter(ParameterSetName='RestrictOutput')] [String] - [ValidateNotNullOrEmpty()] + [ValidateNotNull()] $PathName, [Parameter(ParameterSetName='DefaultOutput')] [Parameter(ParameterSetName='RestrictOutput')] [String] - [ValidateNotNullOrEmpty()] + [ValidateNotNull()] $Description, [Parameter(ParameterSetName='DefaultOutput')] @@ -1783,12 +1783,30 @@ Outputs Win32_Service or Win32_SystemDriver instances both of which derive from $ServiceEntryArgs = @{} if ($PSBoundParameters['Name']) { $FilterComponents.Add("Name LIKE '%$Name%'") } - if ($PSBoundParameters['DisplayName']) { $FilterComponents.Add("DisplayName LIKE '%$DisplayName%'") } + if ($PSBoundParameters.ContainsKey('DisplayName')) { + if ($DisplayName -eq [String]::Empty) { + $FilterComponents.Add('PathName = ""') + } else { + $FilterComponents.Add("PathName LIKE '%$DisplayName%'") + } + } if ($PSBoundParameters['State']) { $FilterComponents.Add("State = '$State'") } if ($PSBoundParameters['StartMode']) { $FilterComponents.Add("StartMode = '$StartMode'") } if ($PSBoundParameters['ServiceType']) { $FilterComponents.Add("ServiceType = '$ServiceType'") } - if ($PSBoundParameters['PathName']) { $FilterComponents.Add("PathName LIKE '%$PathName%'") } - if ($PSBoundParameters['Description']) { $FilterComponents.Add("Description LIKE '%$Description%'") } + if ($PSBoundParameters.ContainsKey('PathName')) { + if ($PathName -eq [String]::Empty) { + $FilterComponents.Add('PathName = ""') + } else { + $FilterComponents.Add("PathName LIKE '%$PathName%'") + } + } + if ($PSBoundParameters.ContainsKey('Description')) { + if ($Description -eq [String]::Empty) { + $FilterComponents.Add('PathName = ""') + } else { + $FilterComponents.Add("PathName LIKE '%$Description%'") + } + } if ($FilterComponents.Count) { $Filter = $FilterComponents -join ' AND ' @@ -1998,13 +2016,13 @@ Outputs Win32_Process instances. [Parameter(ParameterSetName='DefaultOutput')] [Parameter(ParameterSetName='RestrictOutput')] [String] - [ValidateNotNullOrEmpty()] + [ValidateNotNull()] $CommandLine, [Parameter(ParameterSetName='DefaultOutput')] [Parameter(ParameterSetName='RestrictOutput')] [String] - [ValidateNotNullOrEmpty()] + [ValidateNotNull()] $ExecutablePath, [Parameter(ParameterSetName='DefaultOutput')] @@ -2104,8 +2122,20 @@ Outputs Win32_Process instances. if ($PSBoundParameters['Name']) { $FilterComponents.Add("Name LIKE '%$Name%'") } if ($PSBoundParameters['ProcessID']) { $FilterComponents.Add("ProcessID = $ProcessID") } if ($PSBoundParameters['ParentProcessID']) { $FilterComponents.Add("ParentProcessID = $ParentProcessID") } - if ($PSBoundParameters['CommandLine']) { $FilterComponents.Add("CommandLine LIKE '%$CommandLine%'") } - if ($PSBoundParameters['ExecutablePath']) { $FilterComponents.Add("ExecutablePath LIKE '%$ExecutablePath%'") } + if ($PSBoundParameters.ContainsKey('CommandLine')) { + if ($CommandLine -eq [String]::Empty) { + $FilterComponents.Add('ExecutablePath = ""') + } else { + $FilterComponents.Add("ExecutablePath LIKE '%$CommandLine%'") + } + } + if ($PSBoundParameters.ContainsKey('ExecutablePath')) { + if ($ExecutablePath -eq [String]::Empty) { + $FilterComponents.Add('ExecutablePath = ""') + } else { + $FilterComponents.Add("ExecutablePath LIKE '%$ExecutablePath%'") + } + } if ($FilterComponents.Count) { $Filter = $FilterComponents -join ' AND ' From 38c53e0a4fc96b861cceb288a4f92f3c13949d95 Mon Sep 17 00:00:00 2001 From: Matt Graeber Date: Thu, 3 Nov 2016 10:39:48 -0700 Subject: [PATCH 09/15] Get-CSWmiPersistence now also detects persistence in the root/default namespace. Addresses #22 --- CimSweep/CimSweep.psd1 | 1 + CimSweep/Defense/Autoruns.ps1 | 37 ++++++++++++++++++++--------------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/CimSweep/CimSweep.psd1 b/CimSweep/CimSweep.psd1 index e4d8dab..474ec83 100644 --- a/CimSweep/CimSweep.psd1 +++ b/CimSweep/CimSweep.psd1 @@ -55,6 +55,7 @@ PrivateData = @{ Enhancements: * Added Get-CSInstalledAppCompatShimDatabase * Added Get-CSBitlockerKeyProtector +* Get-CSWmiPersistence now also detects persistence in the root/default namespace. Removed: * Removed the -NoProgressBar parameter from all functions since this is what $ProgressPreference is for. diff --git a/CimSweep/Defense/Autoruns.ps1 b/CimSweep/Defense/Autoruns.ps1 index 3b20ddf..2f6a79f 100644 --- a/CimSweep/Defense/Autoruns.ps1 +++ b/CimSweep/Defense/Autoruns.ps1 @@ -636,6 +636,8 @@ Get-CSWmiPersistence only returns output when __FilterToConsumerBinding instance } $Current = 0 + + $TargetNamespaces = @( 'root/subscription', 'root/default' ) } PROCESS { @@ -649,25 +651,28 @@ Get-CSWmiPersistence only returns output when __FilterToConsumerBinding instance Write-Verbose "[$($Session.ComputerName)] Retrieving __FilterToConsumerBinding instance." - Get-CimInstance -Namespace root/subscription -ClassName __FilterToConsumerBinding @CommonArgs | ForEach-Object { - Write-Verbose "[$($Session.ComputerName)] Correlating referenced __EventFilter instance." - $Filter = Get-CimInstance -Namespace root/subscription -ClassName __EventFilter -Filter "Name=`"$($_.Filter.Name)`"" @CommonArgs + foreach ($Namespace in $TargetNamespaces) { + Get-CimInstance -Namespace $Namespace -ClassName __FilterToConsumerBinding @CommonArgs | ForEach-Object { + Write-Verbose "[$($Session.ComputerName)] Correlating referenced __EventFilter instance." + $Filter = Get-CimInstance -Namespace $Namespace -ClassName __EventFilter -Filter "Name=`"$($_.Filter.Name)`"" @CommonArgs + + $ConsumerClass = $_.Consumer.PSObject.TypeNames[0].Split('/')[-1] + Write-Verbose "[$($Session.ComputerName)] Correlating referenced __EventConsumer instance." + $Consumer = Get-CimInstance -Namespace $Namespace -ClassName $ConsumerClass -Filter "Name=`"$($_.Consumer.Name)`"" @CommonArgs + + $ObjectProperties = [Ordered] @{ + PSTypeName = 'CimSweep.WmiPersistence' + Filter = $Filter + ConsumerClass = $ConsumerClass + Consumer = $Consumer + FilterToConsumerBinding = $_ + Namespace = $Namespace + } - $ConsumerClass = $_.Consumer.PSObject.TypeNames[0].Split('/')[-1] - Write-Verbose "[$($Session.ComputerName)] Correlating referenced __EventConsumer instance." - $Consumer = Get-CimInstance -Namespace root/subscription -ClassName $ConsumerClass -Filter "Name=`"$($_.Consumer.Name)`"" @CommonArgs + if ($_.PSComputerName) { $ObjectProperties['PSComputerName'] = $_.PSComputerName } - $ObjectProperties = [Ordered] @{ - PSTypeName = 'CimSweep.WmiPersistence' - Filter = $Filter - ConsumerClass = $ConsumerClass - Consumer = $Consumer - FilterToConsumerBinding = $_ + [PSCustomObject] $ObjectProperties } - - if ($_.PSComputerName) { $ObjectProperties['PSComputerName'] = $_.PSComputerName } - - [PSCustomObject] $ObjectProperties } } } From 6611557654791e2e72164d86ae32a6e9e3e63587 Mon Sep 17 00:00:00 2001 From: Matt Graeber Date: Sun, 13 Nov 2016 08:44:21 -0800 Subject: [PATCH 10/15] Adding Get-CSDeviceGuardStatus --- CimSweep/CimSweep.psd1 | 4 +- CimSweep/Defense/DeviceGuard.ps1 | 142 +++++++++++++++++++++++++++++++ 2 files changed, 145 insertions(+), 1 deletion(-) create mode 100644 CimSweep/Defense/DeviceGuard.ps1 diff --git a/CimSweep/CimSweep.psd1 b/CimSweep/CimSweep.psd1 index 474ec83..2d19b16 100644 --- a/CimSweep/CimSweep.psd1 +++ b/CimSweep/CimSweep.psd1 @@ -37,7 +37,8 @@ FunctionsToExport = @( 'Get-CSAVInfo', 'Get-CSProxyConfig', 'Get-CSInstalledAppCompatShimDatabase', - 'Get-CSBitlockerKeyProtector' + 'Get-CSBitlockerKeyProtector', + 'Get-CSDeviceGuardStatus' ) PrivateData = @{ @@ -56,6 +57,7 @@ Enhancements: * Added Get-CSInstalledAppCompatShimDatabase * Added Get-CSBitlockerKeyProtector * Get-CSWmiPersistence now also detects persistence in the root/default namespace. +* Added Get-CSDeviceGuardStatus Removed: * Removed the -NoProgressBar parameter from all functions since this is what $ProgressPreference is for. diff --git a/CimSweep/Defense/DeviceGuard.ps1 b/CimSweep/Defense/DeviceGuard.ps1 new file mode 100644 index 0000000..98f1195 --- /dev/null +++ b/CimSweep/Defense/DeviceGuard.ps1 @@ -0,0 +1,142 @@ +function Get-CSDeviceGuardStatus { +<# +.SYNOPSIS + +Obtains Device Guard configuration status information + +Author: Matthew Graeber (@mattifestation) +License: BSD 3-Clause + +.DESCRIPTION + +Get-CSDeviceGuardStatus obtains information about available and configured Device Guard settings. This function will only work on systems where Device Guard is available - starting with Windows 10 Enterprise and Server 2016. It relies upon the ROOT\Microsoft\Windows\DeviceGuard:Win32_DeviceGuard WMI class. While returning an instance of a Win32_DeviceGuard class would suffice, it returns numeric values for settings that are not human-readable. + +.PARAMETER CimSession + +Specifies the CIM session to use for this cmdlet. Enter a variable that contains the CIM session or a command that creates or gets the CIM session, such as the New-CimSession or Get-CimSession cmdlets. For more information, see about_CimSessions. + +.EXAMPLE + +Get-CSDeviceGuardStatus + +Lists the available and configured Device Guard settings. + +.OUTPUTS + +CimSweep.DeviceGuardStatus + +Outputs objects representing available and configured Device Guard settings. +#> + + [CmdletBinding()] + [OutputType('CimSweep.DeviceGuardStatus')] + param( + [Alias('Session')] + [ValidateNotNullOrEmpty()] + [Microsoft.Management.Infrastructure.CimSession[]] + $CimSession + ) + + BEGIN { + # If a CIM session is not provided, trick the function into thinking there is one. + if (-not $PSBoundParameters['CimSession']) { + $CimSession = '' + $CIMSessionCount = 1 + } else { + $CIMSessionCount = $CimSession.Count + } + + $CurrentCIMSession = 0 + + # Also applies to RequiredSecurityProperties + $AvailableSecurityPropertiesTable = @{ + 1 = 'BaseVirtualizationSupport' + 2 = 'SecureBoot' + 3 = 'DMAProtection' + 4 = 'SecureMemoryOverwrite' + 5 = 'UEFICodeReadOnly' + 6 = 'SMMSecurityMitigations1.0' + } + + # Also applies to UsermodeCodeIntegrityPolicyEnforcementStatus + $CodeIntegrityPolicyEnforcementStatusTable = @{ + 0 = 'Off' + 1 = 'AuditMode' + 2 = 'EnforcementMode' + } + + # Also applies to SecurityServicesRunning + $SecurityServicesConfiguredTable = @{ + 1 = 'CredentialGuard' + 2 = 'HypervisorEnforcedCodeIntegrity' + } + + $VirtualizationBasedSecurityStatusTable = @{ + 0 = 'Off' + 1 = 'Configured' + 2 = 'Running' + } + } + + PROCESS { + foreach ($Session in $CimSession) { + $ComputerName = $Session.ComputerName + if (-not $Session.ComputerName) { $ComputerName = 'localhost' } + + # Display a progress activity for each CIM session + Write-Progress -Id 1 -Activity 'CimSweep - Device Guard configuration sweep' -Status "($($CurrentCIMSession+1)/$($CIMSessionCount)) Current computer: $ComputerName" -PercentComplete (($CurrentCIMSession / $CIMSessionCount) * 100) + $CurrentCIMSession++ + + $CommonArgs = @{} + + if ($Session.Id) { $CommonArgs['CimSession'] = $Session } + + $DeviceGuardStatus = Get-CimInstance -Namespace ROOT\Microsoft\Windows\DeviceGuard -ClassName Win32_DeviceGuard @CommonArgs + + # An object will not be returned if the namespace/class do not exist + # e.g. <= Win8 and Server 2012 + if ($DeviceGuardStatus) { + # Map numeric settings values to human readable strings. + + # All of these properties are UInt32 values. + # The currently defined values are safe to cast to Int32 + $AvailableSecurityProperties = $DeviceGuardStatus.AvailableSecurityProperties | + ForEach-Object { $AvailableSecurityPropertiesTable[[Int32] $_] } + + $CodeIntegrityPolicyEnforcementStatus = $CodeIntegrityPolicyEnforcementStatusTable[[Int32] $DeviceGuardStatus.CodeIntegrityPolicyEnforcementStatus] + + $RequiredSecurityProperties = $DeviceGuardStatus.RequiredSecurityProperties | + ForEach-Object { $AvailableSecurityPropertiesTable[[Int32] $_] } + + $SecurityServicesConfigured = $DeviceGuardStatus.SecurityServicesConfigured | + ForEach-Object { $SecurityServicesConfiguredTable[[Int32] $_] } + + $SecurityServicesRunning = $DeviceGuardStatus.SecurityServicesRunning | + ForEach-Object { $SecurityServicesConfiguredTable[[Int32] $_] } + + $UsermodeCodeIntegrityPolicyEnforcementStatus = $CodeIntegrityPolicyEnforcementStatusTable[[Int32] $DeviceGuardStatus.UsermodeCodeIntegrityPolicyEnforcementStatus] + + $VirtualizationBasedSecurityStatus = $VirtualizationBasedSecurityStatusTable[[Int32] $DeviceGuardStatus.VirtualizationBasedSecurityStatus] + + $ObjectProperties = [Ordered] @{ + PSTypeName = 'CimSweep.DeviceGuardStatus' + AvailableSecurityProperties = $AvailableSecurityProperties + CodeIntegrityPolicyEnforcementStatus = $CodeIntegrityPolicyEnforcementStatus + InstanceIdentifier = $DeviceGuardStatus.InstanceIdentifier + RequiredSecurityProperties = $RequiredSecurityProperties + SecurityServicesConfigured = $SecurityServicesConfigured + SecurityServicesRunning = $SecurityServicesRunning + UsermodeCodeIntegrityPolicyEnforcementStatus = $UsermodeCodeIntegrityPolicyEnforcementStatus + Version = $DeviceGuardStatus.Version + VirtualizationBasedSecurityStatus = $VirtualizationBasedSecurityStatus + } + + if ($DeviceGuardStatus.PSComputerName) { + $ObjectProperties['PSComputerName'] = $DeviceGuardStatus.PSComputerName + } + + [PSCustomObject] $ObjectProperties + } + } + } +} \ No newline at end of file From a395c9557f9b725f6bc35c98eb003c5b511d6265 Mon Sep 17 00:00:00 2001 From: Matt Graeber Date: Sun, 13 Nov 2016 08:49:50 -0800 Subject: [PATCH 11/15] Folder structure reorg I got rid of the Defense/Offense folders and placed functions into folders that were less generic. I also want to get away from the idea of offense vs. defense. --- CimSweep/{Defense => ArtifactRetrieval}/AppCompatDatabases.ps1 | 0 CimSweep/{Defense => ArtifactRetrieval}/Autoruns.ps1 | 0 CimSweep/{Defense => ArtifactRetrieval}/SuspiciousFiles.ps1 | 0 CimSweep/{Defense => ArtifactRetrieval}/SuspiciousURLs.ps1 | 0 CimSweep/{Offense => Auditing}/ACLAudits.ps1 | 0 CimSweep/{Offense => Auditing}/AntiVirusInfo.ps1 | 0 CimSweep/{Defense => Auditing}/Bitlocker.ps1 | 0 CimSweep/{Defense => Auditing}/DeviceGuard.ps1 | 0 CimSweep/{Offense => Auditing}/ProxyConfig.ps1 | 0 9 files changed, 0 insertions(+), 0 deletions(-) rename CimSweep/{Defense => ArtifactRetrieval}/AppCompatDatabases.ps1 (100%) rename CimSweep/{Defense => ArtifactRetrieval}/Autoruns.ps1 (100%) rename CimSweep/{Defense => ArtifactRetrieval}/SuspiciousFiles.ps1 (100%) rename CimSweep/{Defense => ArtifactRetrieval}/SuspiciousURLs.ps1 (100%) rename CimSweep/{Offense => Auditing}/ACLAudits.ps1 (100%) rename CimSweep/{Offense => Auditing}/AntiVirusInfo.ps1 (100%) rename CimSweep/{Defense => Auditing}/Bitlocker.ps1 (100%) rename CimSweep/{Defense => Auditing}/DeviceGuard.ps1 (100%) rename CimSweep/{Offense => Auditing}/ProxyConfig.ps1 (100%) diff --git a/CimSweep/Defense/AppCompatDatabases.ps1 b/CimSweep/ArtifactRetrieval/AppCompatDatabases.ps1 similarity index 100% rename from CimSweep/Defense/AppCompatDatabases.ps1 rename to CimSweep/ArtifactRetrieval/AppCompatDatabases.ps1 diff --git a/CimSweep/Defense/Autoruns.ps1 b/CimSweep/ArtifactRetrieval/Autoruns.ps1 similarity index 100% rename from CimSweep/Defense/Autoruns.ps1 rename to CimSweep/ArtifactRetrieval/Autoruns.ps1 diff --git a/CimSweep/Defense/SuspiciousFiles.ps1 b/CimSweep/ArtifactRetrieval/SuspiciousFiles.ps1 similarity index 100% rename from CimSweep/Defense/SuspiciousFiles.ps1 rename to CimSweep/ArtifactRetrieval/SuspiciousFiles.ps1 diff --git a/CimSweep/Defense/SuspiciousURLs.ps1 b/CimSweep/ArtifactRetrieval/SuspiciousURLs.ps1 similarity index 100% rename from CimSweep/Defense/SuspiciousURLs.ps1 rename to CimSweep/ArtifactRetrieval/SuspiciousURLs.ps1 diff --git a/CimSweep/Offense/ACLAudits.ps1 b/CimSweep/Auditing/ACLAudits.ps1 similarity index 100% rename from CimSweep/Offense/ACLAudits.ps1 rename to CimSweep/Auditing/ACLAudits.ps1 diff --git a/CimSweep/Offense/AntiVirusInfo.ps1 b/CimSweep/Auditing/AntiVirusInfo.ps1 similarity index 100% rename from CimSweep/Offense/AntiVirusInfo.ps1 rename to CimSweep/Auditing/AntiVirusInfo.ps1 diff --git a/CimSweep/Defense/Bitlocker.ps1 b/CimSweep/Auditing/Bitlocker.ps1 similarity index 100% rename from CimSweep/Defense/Bitlocker.ps1 rename to CimSweep/Auditing/Bitlocker.ps1 diff --git a/CimSweep/Defense/DeviceGuard.ps1 b/CimSweep/Auditing/DeviceGuard.ps1 similarity index 100% rename from CimSweep/Defense/DeviceGuard.ps1 rename to CimSweep/Auditing/DeviceGuard.ps1 diff --git a/CimSweep/Offense/ProxyConfig.ps1 b/CimSweep/Auditing/ProxyConfig.ps1 similarity index 100% rename from CimSweep/Offense/ProxyConfig.ps1 rename to CimSweep/Auditing/ProxyConfig.ps1 From 05f776deae5b6427ffb76a8c405846207cd78041 Mon Sep 17 00:00:00 2001 From: Matt Graeber Date: Sun, 13 Nov 2016 12:00:04 -0800 Subject: [PATCH 12/15] Adding explicit calls to Export-ModuleMember in each script. --- CimSweep/ArtifactRetrieval/AppCompatDatabases.ps1 | 4 +++- CimSweep/ArtifactRetrieval/Autoruns.ps1 | 4 +++- CimSweep/ArtifactRetrieval/SuspiciousFiles.ps1 | 2 ++ CimSweep/ArtifactRetrieval/SuspiciousURLs.ps1 | 4 +++- CimSweep/Auditing/ACLAudits.ps1 | 2 ++ CimSweep/Auditing/AntiVirusInfo.ps1 | 4 +++- CimSweep/Auditing/Bitlocker.ps1 | 4 +++- CimSweep/Auditing/DeviceGuard.ps1 | 4 +++- CimSweep/Auditing/ProxyConfig.ps1 | 4 +++- CimSweep/Core/CoreFunctions.ps1 | 15 +++++++++++++++ 10 files changed, 40 insertions(+), 7 deletions(-) diff --git a/CimSweep/ArtifactRetrieval/AppCompatDatabases.ps1 b/CimSweep/ArtifactRetrieval/AppCompatDatabases.ps1 index fc3e4bb..bfa0e31 100644 --- a/CimSweep/ArtifactRetrieval/AppCompatDatabases.ps1 +++ b/CimSweep/ArtifactRetrieval/AppCompatDatabases.ps1 @@ -112,4 +112,6 @@ Outputs objects representing the relevant information regarding installed applic } } } -} \ No newline at end of file +} + +Export-ModuleMember -Function Get-CSInstalledAppCompatShimDatabase \ No newline at end of file diff --git a/CimSweep/ArtifactRetrieval/Autoruns.ps1 b/CimSweep/ArtifactRetrieval/Autoruns.ps1 index 2f6a79f..7cd5a6e 100644 --- a/CimSweep/ArtifactRetrieval/Autoruns.ps1 +++ b/CimSweep/ArtifactRetrieval/Autoruns.ps1 @@ -676,4 +676,6 @@ Get-CSWmiPersistence only returns output when __FilterToConsumerBinding instance } } } -} \ No newline at end of file +} + +Export-ModuleMember -Function Get-CSRegistryAutoStart, Get-CSStartMenuEntry, Get-CSWmiPersistence \ No newline at end of file diff --git a/CimSweep/ArtifactRetrieval/SuspiciousFiles.ps1 b/CimSweep/ArtifactRetrieval/SuspiciousFiles.ps1 index 150582f..ee5820e 100644 --- a/CimSweep/ArtifactRetrieval/SuspiciousFiles.ps1 +++ b/CimSweep/ArtifactRetrieval/SuspiciousFiles.ps1 @@ -622,3 +622,5 @@ Outputs CIM_DataFile instances of files present in low-integrity level directori } } } + +Export-ModuleMember -Function Get-CSScheduledTaskFile, Get-CSShellFolderPath, Get-CSTempFile, Get-CSLowILPathFile \ No newline at end of file diff --git a/CimSweep/ArtifactRetrieval/SuspiciousURLs.ps1 b/CimSweep/ArtifactRetrieval/SuspiciousURLs.ps1 index 044fe27..846608c 100644 --- a/CimSweep/ArtifactRetrieval/SuspiciousURLs.ps1 +++ b/CimSweep/ArtifactRetrieval/SuspiciousURLs.ps1 @@ -79,4 +79,6 @@ Outputs the registry values consisting of typed IE URLs. } } } -} \ No newline at end of file +} + +Export-ModuleMember -Function Get-CSTypedURL \ No newline at end of file diff --git a/CimSweep/Auditing/ACLAudits.ps1 b/CimSweep/Auditing/ACLAudits.ps1 index c93be08..71c68f6 100644 --- a/CimSweep/Auditing/ACLAudits.ps1 +++ b/CimSweep/Auditing/ACLAudits.ps1 @@ -207,3 +207,5 @@ Service ACL sweep across a large amount of hosts will take a long time. } } } + +Export-ModuleMember -Function Get-CSVulnerableServicePermission \ No newline at end of file diff --git a/CimSweep/Auditing/AntiVirusInfo.ps1 b/CimSweep/Auditing/AntiVirusInfo.ps1 index 1f71532..25c5a91 100644 --- a/CimSweep/Auditing/AntiVirusInfo.ps1 +++ b/CimSweep/Auditing/AntiVirusInfo.ps1 @@ -173,4 +173,6 @@ Outputs custom objects representing the current AV configuration. $AntiVirus } } -} \ No newline at end of file +} + +Export-ModuleMember -Function Get-CSAVInfo \ No newline at end of file diff --git a/CimSweep/Auditing/Bitlocker.ps1 b/CimSweep/Auditing/Bitlocker.ps1 index 18fbb6f..a5b97b9 100644 --- a/CimSweep/Auditing/Bitlocker.ps1 +++ b/CimSweep/Auditing/Bitlocker.ps1 @@ -275,4 +275,6 @@ Outputs objects representing Bitlocker volume key material. } } } -} \ No newline at end of file +} + +Export-ModuleMember -Function Get-CSBitlockerKeyProtector \ No newline at end of file diff --git a/CimSweep/Auditing/DeviceGuard.ps1 b/CimSweep/Auditing/DeviceGuard.ps1 index 98f1195..df4a307 100644 --- a/CimSweep/Auditing/DeviceGuard.ps1 +++ b/CimSweep/Auditing/DeviceGuard.ps1 @@ -139,4 +139,6 @@ Outputs objects representing available and configured Device Guard settings. } } } -} \ No newline at end of file +} + +Export-ModuleMember -Function Get-CSDeviceGuardStatus \ No newline at end of file diff --git a/CimSweep/Auditing/ProxyConfig.ps1 b/CimSweep/Auditing/ProxyConfig.ps1 index 95eed8c..0451caf 100644 --- a/CimSweep/Auditing/ProxyConfig.ps1 +++ b/CimSweep/Auditing/ProxyConfig.ps1 @@ -117,4 +117,6 @@ CimSweep.ProxyConfig $ProxySettings } } -} \ No newline at end of file +} + +Export-ModuleMember -Function Get-CSProxyConfig \ No newline at end of file diff --git a/CimSweep/Core/CoreFunctions.ps1 b/CimSweep/Core/CoreFunctions.ps1 index fa288d3..fbd0967 100644 --- a/CimSweep/Core/CoreFunctions.ps1 +++ b/CimSweep/Core/CoreFunctions.ps1 @@ -2594,3 +2594,18 @@ Microsoft.Management.Infrastructure.CimInstance#root/__NAMESPACE } } } + +$ToExport = @( + 'Get-CSRegistryKey', + 'Get-CSRegistryValue', + 'Get-CSEventLog', + 'Get-CSEventLogEntry', + 'Get-CSMountedVolumeDriveLetter', + 'Get-CSDirectoryListing', + 'Get-CSService', + 'Get-CSProcess', + 'Get-CSEnvironmentVariable', + 'Get-CSWmiNamespace' +) + +Export-ModuleMember -Function $ToExport \ No newline at end of file From 7e6700caaa7096873c4327b7f723b4edc3ed8d11 Mon Sep 17 00:00:00 2001 From: Matt Graeber Date: Sat, 13 May 2017 08:48:16 -0700 Subject: [PATCH 13/15] Minor updates See CimSweep.psd1 for a detailed changelog --- CimSweep/CimSweep.psd1 | 6 ++++++ CimSweep/Core/CoreFunctions.ps1 | 21 +++++++++++---------- CimSweep/Tests/Core.CimSweep.Tests.ps1 | 16 ++++++---------- CimSweep/Tests/Module.Tests.ps1 | 2 +- 4 files changed, 24 insertions(+), 21 deletions(-) diff --git a/CimSweep/CimSweep.psd1 b/CimSweep/CimSweep.psd1 index 2d19b16..d057c61 100644 --- a/CimSweep/CimSweep.psd1 +++ b/CimSweep/CimSweep.psd1 @@ -58,12 +58,18 @@ Enhancements: * Added Get-CSBitlockerKeyProtector * Get-CSWmiPersistence now also detects persistence in the root/default namespace. * Added Get-CSDeviceGuardStatus +* Added positional parameters for Name parameters for Get-CSEventLogEntry, Get-CSService, Get-CSProcess, Get-CSEnvironmentVariable, and Get-CSWmiNamespace. Removed: * Removed the -NoProgressBar parameter from all functions since this is what $ProgressPreference is for. * Removed Set-DefaultDisplayProperty helper function and all calls to it. It was creating unnecessary code complexity. * Removed -OperationTimeoutSec param from all functions. Was creating unnecessary code complexity. +General changes: +* Reorganized the folder structure and removed any offensive code. +* A decision was also made that CimSweep will only ever have Get- functions. Considering CimSweep is designed to pull information at scale, it should never perform any action that would change system state. +* Applied PSScriptAnalyzer rules to test code and addressed its findings. + 0.5.1 ----- Enhancements: diff --git a/CimSweep/Core/CoreFunctions.ps1 b/CimSweep/Core/CoreFunctions.ps1 index fbd0967..63460bf 100644 --- a/CimSweep/Core/CoreFunctions.ps1 +++ b/CimSweep/Core/CoreFunctions.ps1 @@ -770,9 +770,9 @@ Outputs Win32_NtLogEvent instances. [OutputType('Microsoft.Management.Infrastructure.CimInstance#root/cimv2/Win32_NTLogEvent')] [CmdletBinding(DefaultParameterSetName='DefaultOutput')] param( - [Parameter(ParameterSetName='DefaultOutput')] - [Parameter(ParameterSetName='RestrictOutput')] - [Parameter(ValueFromPipelineByPropertyName = $True)] + [Parameter(Position = 0, ParameterSetName='DefaultOutput')] + [Parameter(Position = 0, ParameterSetName='RestrictOutput')] + [Parameter(Position = 0, ValueFromPipelineByPropertyName = $True)] [String] $LogName, @@ -1549,8 +1549,8 @@ Outputs Win32_Service or Win32_SystemDriver instances both of which derive from [CmdletBinding(DefaultParameterSetName='DefaultOutput')] [OutputType('Microsoft.Management.Infrastructure.CimInstance#ROOT/cimv2/Win32_BaseService')] param( - [Parameter(ParameterSetName='DefaultOutput')] - [Parameter(ParameterSetName='RestrictOutput')] + [Parameter(Position = 0, ParameterSetName='DefaultOutput')] + [Parameter(Position = 0, ParameterSetName='RestrictOutput')] [String] [ValidateNotNullOrEmpty()] $Name, @@ -1996,8 +1996,8 @@ Outputs Win32_Process instances. [CmdletBinding(DefaultParameterSetName='DefaultOutput')] [OutputType('Microsoft.Management.Infrastructure.CimInstance#root/cimv2/Win32_Process')] param( - [Parameter(ParameterSetName='DefaultOutput')] - [Parameter(ParameterSetName='RestrictOutput')] + [Parameter(Position = 0, ParameterSetName='DefaultOutput')] + [Parameter(Position = 0, ParameterSetName='RestrictOutput')] [String] [ValidateNotNullOrEmpty()] $Name, @@ -2210,9 +2210,9 @@ Outputs objects consisting of the name, value, and scope (user vs. system) of an [CmdletBinding(DefaultParameterSetName = 'Default')] [OutputType('CimSweep.EnvironmentVariable')] param( - [Parameter(ParameterSetName = 'Default')] - [Parameter(ParameterSetName = 'System')] - [Parameter(ParameterSetName = 'User')] + [Parameter(Position = 0, ParameterSetName = 'Default')] + [Parameter(Position = 0, ParameterSetName = 'System')] + [Parameter(Position = 0, ParameterSetName = 'User')] [Alias('Name')] [String] [ValidateNotNullOrEmpty()] @@ -2447,6 +2447,7 @@ Microsoft.Management.Infrastructure.CimInstance#root/__NAMESPACE [CmdletBinding()] [OutputType('Microsoft.Management.Infrastructure.CimInstance#root/__NAMESPACE')] Param ( + [Parameter(Position = 0)] [String] [ValidateNotNullOrEmpty()] $Namespace = 'ROOT', diff --git a/CimSweep/Tests/Core.CimSweep.Tests.ps1 b/CimSweep/Tests/Core.CimSweep.Tests.ps1 index b7513bf..858e892 100644 --- a/CimSweep/Tests/Core.CimSweep.Tests.ps1 +++ b/CimSweep/Tests/Core.CimSweep.Tests.ps1 @@ -298,13 +298,13 @@ Describe 'Get-CSRegistryValue' { Describe 'Get-CSEventLog' { It 'should return output' { - $Result = Get-CSEventLog | Select -First 1 + $Result = Get-CSEventLog | Select-Object -First 1 $Result.LogName | Should Not BeNullOrEmpty } It 'should return output with CIM sessions' { - $Result = Get-CSEventLog -CimSession $TestSessionArray | Select -First 1 + $Result = Get-CSEventLog -CimSession $TestSessionArray | Select-Object -First 1 $Result.LogName | Should Not BeNullOrEmpty $Result.PSComputerName | Should BeExactly 'localhost' @@ -522,7 +522,7 @@ Describe 'Get-CSDirectoryListing' { } It 'should recurse one folder deep by piping output to itself w/ CIM sessions' { - $ConfigDir = Get-CSDirectoryListing -DirectoryPath $SystemDirectory -Directory -CimSession $TestCimSession1 | Where-Object { $_.Name -eq "$SystemDirectory\config" } + $ConfigDir = Get-CSDirectoryListing -DirectoryPath $SystemDirectory -Directory -CimSession $TestCimSession1 | Where-Object { $_.Name -eq "$SystemDirectory\drivers" } $ConfigDirListing = $ConfigDir | Get-CSDirectoryListing | Select-Object -First 1 $ConfigDirListing | Should Not BeNullOrEmpty @@ -632,8 +632,6 @@ Describe 'Get-CSDirectoryListing' { $TempFileDir = Split-Path $TempFile -Parent $TempFileName = Split-Path $TempFile -Leaf - $TempFileDetails = Get-ChildItem $TempFile - $TempFile | Should Exist $FileContents = Get-Content $TempFile $FileContents | Should BeExactly ([Text.Encoding]::ASCII.GetString($FileBytes)) @@ -686,8 +684,6 @@ Describe 'Get-CSDirectoryListing' { $TempFileDir = Split-Path $TempFile -Parent $TempFileName = Split-Path $TempFile -Leaf - $TempFileDetails = Get-ChildItem $TempFile - $TempFile | Should Exist $FileContents = Get-Content $TempFile $FileContents | Should BeExactly ([Text.Encoding]::ASCII.GetString($FileBytes)) @@ -763,7 +759,7 @@ Describe 'Get-CSService' { $AppDomain = [Reflection.Assembly].Assembly.GetType('System.AppDomain').GetProperty('CurrentDomain').GetValue($null) $ServiceSecurityType = $AppDomain.GetAssemblies() | Where-Object { ($_.FullName.StartsWith('CimSweepAssembly')) -and ($_.GetType('CimSweep.ServiceSecurity')) - } | Select -First 1 + } | Select-Object -First 1 $ServiceSecurityType | Should Not BeNullOrEmpty } @@ -1085,7 +1081,7 @@ Describe 'Get-CSWmiNamespace' { It 'should recurse over namespaces' { # Ignore errors since you may not have permission to retrieve all namespaces as an unprivileged user. - $AllNamespaces = Get-CSWmiNamespace -ErrorAction SilentlyContinue -Recurse | Select -First 10 + $AllNamespaces = Get-CSWmiNamespace -ErrorAction SilentlyContinue -Recurse | Select-Object -First 10 $CIMv2Namespaces = Get-CSWmiNamespace -Namespace 'ROOT/CIMV2' -ErrorAction Stop @@ -1099,7 +1095,7 @@ Describe 'Get-CSWmiNamespace' { $AppDomain = [Reflection.Assembly].Assembly.GetType('System.AppDomain').GetProperty('CurrentDomain').GetValue($null) $WmiNamespaceSecurityType = $AppDomain.GetAssemblies() | Where-Object { ($_.FullName.StartsWith('CimSweepAssembly')) -and ($_.GetType('CimSweep.WmiNamespaceSecurity')) - } | Select -First 1 + } | Select-Object -First 1 $WmiNamespaceSecurityType | Should Not BeNullOrEmpty } diff --git a/CimSweep/Tests/Module.Tests.ps1 b/CimSweep/Tests/Module.Tests.ps1 index b8e3985..115f136 100644 --- a/CimSweep/Tests/Module.Tests.ps1 +++ b/CimSweep/Tests/Module.Tests.ps1 @@ -66,7 +66,7 @@ Describe 'Module-wide tests' -Tags 'Module' { $ASTParameters = @($AST.ParamBlock.Parameters.Name.Variablepath.Userpath) It 'should contain a matching number of .PARAMETER blocks for all defined parameters' { - $NamedArgs = try { $AST.ParamBlock.Attributes.NamedArguments } catch {} + $NamedArgs = try { $AST.ParamBlock.Attributes.NamedArguments } catch { $null } if ($NamedArgs -and $NamedArgs.ArgumentName -contains 'SupportsShouldProcess') { $Count = $ASTParameters.Count + 2 # Accounting for -WhatIf and -Confirm From 5d73b1da58d5d9319fa2ef623321ae1b080c7df5 Mon Sep 17 00:00:00 2001 From: Matt Graeber Date: Sat, 13 May 2017 08:55:52 -0700 Subject: [PATCH 14/15] Update README.md Fixed build status rendering --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 57f63b5..392737d 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ -|Master | Dev | -|:------:|:------:|:-------:|:-------:| -[![Build status](https://ci.appveyor.com/api/projects/status/58jy9aie7w6aac0y/branch/master?svg=true)](https://ci.appveyor.com/project/mattifestation/cimsweep/branch/master)|[![Build status](https://ci.appveyor.com/api/projects/status/58jy9aie7w6aac0y/branch/dev?svg=true)](https://ci.appveyor.com/project/mattifestation/cimsweep/branch/dev) | +#### Master +[![Build status](https://ci.appveyor.com/api/projects/status/58jy9aie7w6aac0y/branch/master?svg=true)](https://ci.appveyor.com/project/mattifestation/cimsweep/branch/master) +#### Dev +[![Build status](https://ci.appveyor.com/api/projects/status/58jy9aie7w6aac0y/branch/dev?svg=true)](https://ci.appveyor.com/project/mattifestation/cimsweep/branch/dev) # CimSweep CimSweep is a suite of CIM/WMI-based tools that enable the ability to perform incident response and hunting operations remotely across all versions of Windows. CimSweep may also be used to engage in offensive reconnaisance without the need to drop any payload to disk. Windows Management Instrumentation has been installed and its respective service running by default since Windows XP and Windows 2000 and is fully supported in the latest versions of Windows including Windows 10, Nano Server, and Server 2016. From 8c80b62790ce60da0edbb5c64ed0ed5b19639661 Mon Sep 17 00:00:00 2001 From: Matt Graeber Date: Sat, 13 May 2017 09:00:54 -0700 Subject: [PATCH 15/15] Included signed catalog file Final prep for 0.6 release and PS Gallery publishing. --- CimSweep/CimSweep.cat | Bin 0 -> 12655 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 CimSweep/CimSweep.cat diff --git a/CimSweep/CimSweep.cat b/CimSweep/CimSweep.cat new file mode 100644 index 0000000000000000000000000000000000000000..84b5ae931cbb50c3af0f760a90759581cdf45013 GIT binary patch literal 12655 zcmeHud0foj_y4?Rrm04onl@U7R%v;?+O$~Ol`LsP64Rcx(M*dZW+YOf6jISfrIJD< zOOlekg~%2PQAxC-zW0?TMLzLGitX>zsS;Ip=xqxfjetJPDi%;ilm| z+z>l9g^Ae1Ok_D0f{;ltCxLAy4-Pwp4FfX;T?w2s2@oD)<o7Ou=QK$_nNp5Qi(d zAPCRL@kLw|%e!TM4wU|`&-@ravXBYz;`! zz(i?aT^51qI)mw=%c_j|)-r19jMsRw{x!W;?(3TZ_zHzgn%fg(HDagJo2P9kly;rT zKs;Nu5ys_lc(NJc2@Bzo`LOY*K3GUJ4Z9fwBQQ6Cb4|D@FZn-c_Hhx_yi%r(8Iu;n(j2BaF&X)8HC5m%ldEiD<$0BNF7o zLdarx;ZIjp6;)nmpiZbI`e59^+FAfb_QeEY)?*C8(+Ak62dE#lvOuY=1k1<~rY>px z)Ijscvj$%&?7!Om&nUI?uu^ZwlUxKBizYOrwK`nfbV2ZLN~8ZR-J=L~9I5`T=^Fu+ z4ggbj0?+wCI20fb=h4$=^y0~GYQom`2C!z)ad+v-05%6T%5$Sb1`PyS$b`UJ3ywh@d&+N{g$6l{P0m*1Y)6#pzpgRM?T=aU|tBMpDaR+n-8m_BRl;A99?2L(upm zQh)0=%B3Q4qoKbPj3ao`fUL$Y(mgzRpWM}|n!_oIutdI@KtfoI{Du3}6TzdY-bM;Ha;h~sZZQNw`q*Tgyz&oCn!PdZxDxqcwp z^L_5goAPq6=`&{>qufOpyT_T#f4m4FtT`^fhI^*pqO>ljc@B&fUN}yN3cQ-cX@tY9 z6w0AAwf@PlW+GaDFRYmu*FnHqoRN=Mq*@>7&Yqc^b<_aaBU^e|FXDc`%8XdQj5A@m ze==a5h}Q1}tZ1Z$I-GB=#{@uy&(OXK-8X%=En#%v$yHL+1ybDH0v7irrc9lb*?({L z!*_4s0YqVQkKmVJ0~dsGeH@MaYi2PKE%={DNG62GldE?HXFu!fk&8>k55=^vZ(M6}@l2!*@x1~QD^W4=0r*8`wQmN! zdE$E3WWL+G6hsZxe@qM$(SrXih(-6K_3KNYW+5{+neXcS(t59J`Q9VNy}?j0u~kFH zM?@t^@=u!gM6`a#yuXDqtWBB$hz99k`|S%%+!GkS-nML_EU`unTN5F<8xZu$dyFiEQS`E-s8P zjhg%CcYzabg3)O9{S7v~JGoGPKt7Gp6BJVLiu)De&quTWd#M2%orC>sjd2MkdDW8& zYGx#KH8GiTf0vEl1r%UhAC9dJ2*`Mjmb+hAw_|vYC$)A_@zm)sqDH0s{k;ok5cm zXi|3a^+pg_1#Q9!$d8P$GSycl>(gldelE^rGb6I0ud@r;%EQga!^e$ms1Hkk)UGD1 zrK%1O{j(d&^lGVUBdTcG4t5;N6Pil~6gUL1%k&X`;QT>>U4YZd$JgE0+k@tgh`>T< z9Z`UH5rs~7cL^lV_oKKty7;kLa6h!bOlbOOQGhHRjtTLCTs1_*G9d`FZ^6m!r!MUD ztoNvO_1NKmqBv6ET1UzW3APJMa`=<``*(|3g|jYTJ)26!)Rc z7V{t2UdVo`Do!pbV6xJbeHqF%3^#ICr>W0V&bti?9oi)^eR(D|H{JG@?96VG5s!?X z&2@*6AG2~!#krezH-+-M=7a>feSVPqd}Du3ibbpXD)!p4s%1J34!vFVZ?!ITZ+Orq z`+jetDhGd%4%2vxynF3HRcGFdS=Q{Xj}{hh@%UVL3FDProoy80+aXKjE`rX)J`nSF z!Re<+7%MM*ZOJ?(N4U|}aQ<UQzxSq_V%9eD6Ucv9H)N7(kB zPkv_niqsDc;+J1*-lc%tJ!s~Ipg}wyhh^V9q-5eUcrKVo-~eX;Y;5c}92|&tlEhPC zA6O$rEd>czai`O%Iw~qoeqL&0lum`_PEl2&eAO@|Cz_HQq6|9yI86PQhAl)1lkvu| zAw27A;x_z?7Y>3IV0jjMSV%|=<%R~>`Q8Ln3@xl+4g$fA!3B;uU`7~g5IEHcf&*Y_ zRvCuEMTV#3>qMiD;SF9q(hD1Iz?wJ(H8a|njw&oOL#=Gs$jppT6C1WLLwz6%IyhYc zlM+Bhj)gI!RUKG8P<06787c0veqW+rHP^e&tEQpzwRr*yZ|8?`TpZjOZg3kpx=((W z@=SA8Oix@!Tlp;;34^L_D>`k(iHZVU+2yjmD@&&4f?Cou1=EdyRVx%N4O)0NYSnmSIy6ewLUW=aYIJANU`*^zK>Rs0ot?q z@lFj5_kC!0B#4JKUg#*bI-EGEu;6_*^O~twwcS>3ixA9Fk=*2@O?wE^!qz^)SK@p4 zQcSRKbpu``R*MyLYF(Z-MXNQBW8N&g&Aqmv6~U(E8xL9WMqMV}R7}1TXVUwq$T4BT zlIX3`mcEuVcb_FUMhJB5z6cy83>>A%u%pCticDR7x5U-o%J7tLyamU1B7q}?(Ml}RhRULMQ!rZD_ql*8Dzn;if_ST*d+r%?D-z|{6 zb`oMHdi%~N+EVRSTk&azTxIPBsko*XslB@cnSH5YQm*{gY8LbYdD#+akFqk$PLkV>2;(}X z)by6^isblXVhgr$Jmu0wFpG?_zZYq3>N=e zZW!Rn@JQS!Od1!mMq`@s+qC?TvDcZ1($dJx%xTFVysz?p=KzL$=G<0pJLwZ2rdJDI zRSc1t5s)RmN=!*-O8GmOQXe{L&6mq_c+2x6zr0g;O17DG{8@K(tUvG4lRk%c+C6uW zW-R8*XrH%krxTBWd0zc$qxBy&NrW9eNhXW!2X_}tW#@?z{B$<|)Y7tO>0{Crm2wKH zGvue}tdqyiR*p$8m6`lJi8Mbo*xfxpG1H!G|6pAK*RGPR-Yfj>hi>a#*E2dS(DBll zONPThwNP`1GXB?4@o+&cp2ik$ulb1rZ@J*!Mk=&E3sx454PO$ zb!~rqeQV3=!+mwz=-Z8SMXQ>-Vh&Z1v~#83WSJ|*MBH$Y|L9y~ak`8D1Z^+TE&T%J z(6J9+_=Eg;j;thoF_zjHZe+7jB%CeEX4`sGlb&ll(V0&cuYR6Yq_hG{*-r5jaW6g- z(*E+5x(X7=fF(;bq3CyVFM1AiEJU26U%c%X-If)4yETeSb7k+wLuH#QtW<8^TvG&mU@0&)NuU;OF?m{1WY6oOysNJPdCfnw}$ z#AHm!ndKa@STNRBf(coIqZc1=d`uoXt#ScRUvP*_2KfqikhP$JH^ZTf#n;Op=t(Pj z9)R|98ctQBEp#v%twsBz7evtWSSqNY45c;4eibblfiZ62$NDx(#R8);^w(H>$jcLIOOU>th?0_E}R zJ9>(N-f=-|(D5jbC@u8t7^Q{MK^fYJjssUL z;7KD(gcBUIRS?AR&lK2Sn84m9@igtiGVYmf*qfu=GR1C@bdi~A@&bkRQ?{6Yl!&-= zZ6mx9RRBqR08EDg4yCAvtA0bGiO>Xf2tylzA4X1uVIw00SsDXC*c0~nMG)3!jRGL7 z!Q%IS1@9x^IZT-To$DMzn`D{LscMS~Wf}H~;kTs7yqmW*Zyy{is9URuwCM1So1&e_}zhbm#y%V_DwH(+7^Pk$vN_Y}zVy70GqSx5SCE zd1~zDOWClmvU}dE=aco1oOgWCAvZ@$T;5m5lCz_g>R9V&e!P)(B(}76Cvsoqg}1N( zp}h%LM9TTF%P@0Y^0ddKYl5p{^&9$l8Py4NZrO64O;b;GrM#~QB*+W4+~3n|Bh*ns z%n^HNZz|_{H9e9j)*Rn(tXz3T3gvOb2k$gW%Z^Fjt^6YAdu*)raIrHz%a)cAP4kb} z`80kc5p|}%*fr-`{@UmbkM0`*v;iR%+bLEm<4YfIFD~y5hWK`#T*=v~--+yBjL>0C z1mr!w0S+jQ6#o^_nI(l3ti}tie25WNQa=6q7M9i22 zm6eF;<`9WA-dG-ss)}uIHRs)jFApB+`IL6kmnJokYs6M0$ zv9ERKv=!*5x6QloFy6GhUE)ONIj)%rcPdu#8!(=2@nO>D$(oaPA6wx{ERViWbBk~+ zFU;38EOCim@%x3H`TIY0-_l!U-<|bdCBHRddZ(v|OTi^tUj6&~wcy)Z$D5xbm3Ehv)|`qv@35qRt%hgLlx)(< zBjJc+R+d^*qIPC^*Ddj&fH)ailS0nzqyY1_)n(>FP3F{vm-il0F^jTqAo*A-beth7%M+H;O&BgeV0!f#Wm#EmqbIjnAMVNRU zkaE(*LLf~T{$J#B#yJr9c2PSe5EdCZ9pJrIu)j=nGKxZ6@oh`?Rw5m^Vf2P_Fi+~v9w z;%co|3e?vnmf#cNyN~LNa(EoA9(3ti%%KIn+@oOmZpU`*+y-~`msgyX#6l=~%;K(g z>jgf~!dD(meVIhk6_Dno8XLrI#TZ(+=x65JOSWyhLAkQ}MjW-Ya$d^y3>T7sQD^iph>^ZK-C+nGz+N^i(LDtDs zCYBdwV!;v&pVn{^5GM2)phGXJJpunln1SW{VS_(PSyug^EUfl0xw{(3P2O*o-wi--e+yRE05^WCc82d-w($93V{S)dL-6wV28)m(FIe898 z|MJRwxT{XwDgIJTolS^IN&Uw<9%))$m@e*I<-$kivLV#dT!akN8sJL73pI7bg@@t$O=aI-)#-$hdOg2P(dK2Z{>Z7+kPpG+3Z+_k#$UUx&g z5qDz*&(R%`QK~VGYNw|e?T$P++4XbqPO*549akKtGwzQ^e@||`c3Zr1ij1@Em-VR^i3k4=ayM!- literal 0 HcmV?d00001