From 21a72cdd3391d0694ef84a7fd92a9700d72dc014 Mon Sep 17 00:00:00 2001 From: Thumbscrew Date: Fri, 3 Jan 2020 11:23:25 +0000 Subject: [PATCH 1/2] Added switch for inferring remote computer's log path based on local reg settings. --- public/Get-PSFirewallLog.ps1 | 15 +++- public/Get-PSFirewallLogPath.ps1 | 137 ++++++++++++++++++------------- 2 files changed, 91 insertions(+), 61 deletions(-) diff --git a/public/Get-PSFirewallLog.ps1 b/public/Get-PSFirewallLog.ps1 index 7d54ced..188495e 100644 --- a/public/Get-PSFirewallLog.ps1 +++ b/public/Get-PSFirewallLog.ps1 @@ -36,7 +36,12 @@ function Get-PSFirewallLog { # Follow the log [Parameter(Mandatory = $false)] [switch] - $Wait + $Wait, + + # Use local machine's registry setting to infer remote machine's log path + [Parameter(Mandatory = $false, ParameterSetName = 'remote')] + [switch] + $InferPath ) begin { @@ -44,7 +49,13 @@ function Get-PSFirewallLog { $Path = Get-PSFirewallLogPath -LogProfile $LogProfile -Verbose:$VerbosePreference } elseif($PSCmdlet.ParameterSetName -eq 'remote') { - $Path = Get-PSFirewallLogPath -LogProfile $LogProfile -ComputerName $ComputerName -Verbose:$VerbosePreference + $lpc = "Get-PSFirewallLogPath -LogProfile $LogProfile -ComputerName $ComputerName" + + if($InferPath) { + $lpc += " -InferPath" + } + + $Path = Invoke-Expression $lpc -Verbose:$VerbosePreference } } diff --git a/public/Get-PSFirewallLogPath.ps1 b/public/Get-PSFirewallLogPath.ps1 index 1e711c7..3586942 100644 --- a/public/Get-PSFirewallLogPath.ps1 +++ b/public/Get-PSFirewallLogPath.ps1 @@ -9,75 +9,92 @@ function Get-PSFirewallLogPath { # Remote Host to retrieve from [Parameter(Mandatory = $false, ParameterSetName = 'remote')] [string] - $ComputerName + $ComputerName, + + # Use local machine's registry setting to infer remote machine's log path + [Parameter(Mandatory = $false, ParameterSetName = 'remote')] + [switch] + $InferPath ) process { - $serviceName = "RemoteRegistry" - if($PSCmdlet.ParameterSetName -eq 'remote') { - $startTypeChanged = $false - $statusChanged = $false - Write-Verbose "Retrieving path from registry on host $ComputerName." - $remoteRegistry = Get-Service -ComputerName $ComputerName -Name $serviceName - - if($remoteRegistry.StartType -eq "Disabled") { - Write-Verbose "$serviceName service is Disabled. Attempting to change to Manual startup." - Set-Service -StartupType "Manual" -Name $serviceName -ComputerName $ComputerName - $modifiedRemoteRegistry = Get-Service -Name $serviceName -ComputerName $ComputerName + if($InferPath) { + # Get local registry key entry + $localPath = [Environment]::ExpandEnvironmentVariables((Get-ItemProperty -Path ("HKLM:\SOFTWARE\Policies\Microsoft\WindowsFirewall\{0}Profile\Logging" -f $LogProfile) -Name "LogFilePath").LogFilePath) - if($modifiedRemoteRegistry.StartType -ne "Manual") { - Write-Warning "Unable to change startup of $serviceName on host $ComputerName." - return $null - } - else { - Write-Verbose "$serviceName startup changed to Manual." - $startTypeChanged = $true + if($null -eq $localPath) { + $defaultPath = "$ENV:SystemRoot\system32\LogFiles\Firewall\pfirewall.log" + Write-Warning "Path for $LogProfile firewall log not defined in registry. Assuming default path of $defaultPath" + $localPath = $defaultPath } } + else { + $serviceName = "RemoteRegistry" + $startTypeChanged = $false + $statusChanged = $false - if($remoteRegistry.Status -ne "Running") { - Write-Verbose "$serviceName service is not running. Attempting to start." - Set-Service -Status "Running" -Name $serviceName -ComputerName $ComputerName - $modifiedRemoteRegistry = Get-Service -Name $serviceName -ComputerName $ComputerName - - if($modifiedRemoteRegistry.Status -eq "Stopped") { - Write-Warning "Unable to start $serviceName service on host $ComputerName." - return $null - } - else { - Write-Verbose "$serviceName service started OK." - $statusChanged = $true - } - } - - $reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $ComputerName) - $regKey = $reg.OpenSubKey("SOFTWARE\\Policies\\Microsoft\\WindowsFirewall\\{0}Profile\Logging" -f $LogProfile) - $localPath = [Environment]::ExpandEnvironmentVariables($RegKey.GetValue("LogFilePath")) - - # Set Remote Registry back the way we found it if we had to change it - - if($statusChanged) { - Write-Verbose ("Reverting status of $serviceName Service to {0}." -f $remoteRegistry.Status) - # Set-Service -Name $serviceName -ComputerName $ComputerName -Status $remoteRegistry.Status - # Need to use Invoke-Command as Set-Service won't stop a service that has dependencies - Invoke-Command -ComputerName $ComputerName -ScriptBlock { Stop-Service -Name "RemoteRegistry" } + Write-Verbose "Retrieving path from registry on host $ComputerName." + $remoteRegistry = Get-Service -ComputerName $ComputerName -Name $serviceName - # Verify that service has been restored to its original state. - $revertedRemoteRegistry = Get-Service -Name $serviceName -ComputerName $ComputerName - if($remoteRegistry.Status -ne $revertedRemoteRegistry.Status) { - Write-Warning "Failed to revert $serviceName status to $($remoteRegistry.Status)!" - } - } + if($remoteRegistry.StartType -eq "Disabled") { + Write-Verbose "$serviceName service is Disabled. Attempting to change to Manual startup." + Set-Service -StartupType "Manual" -Name $serviceName -ComputerName $ComputerName + $modifiedRemoteRegistry = Get-Service -Name $serviceName -ComputerName $ComputerName - if($startTypeChanged) { - Write-Verbose ("Reverting Startup of $serviceName Service to {0}." -f $remoteRegistry.StartType) - Set-Service -Name $serviceName -ComputerName $ComputerName -StartupType $remoteRegistry.StartType - - # Verify that service has been restored to its original state. - if($remoteRegistry.StartType -ne $revertedRemoteRegistry.StartType) { - Write-Warning "Failed to revert startup type of $serviceName to $($remoteRegistry.StartType)!" + if($modifiedRemoteRegistry.StartType -ne "Manual") { + Write-Warning "Unable to change startup of $serviceName on host $ComputerName." + return $null + } + else { + Write-Verbose "$serviceName startup changed to Manual." + $startTypeChanged = $true + } + } + + if($remoteRegistry.Status -ne "Running") { + Write-Verbose "$serviceName service is not running. Attempting to start." + Set-Service -Status "Running" -Name $serviceName -ComputerName $ComputerName + $modifiedRemoteRegistry = Get-Service -Name $serviceName -ComputerName $ComputerName + + if($modifiedRemoteRegistry.Status -eq "Stopped") { + Write-Warning "Unable to start $serviceName service on host $ComputerName." + return $null + } + else { + Write-Verbose "$serviceName service started OK." + $statusChanged = $true + } + } + + $reg = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $ComputerName) + $regKey = $reg.OpenSubKey("SOFTWARE\\Policies\\Microsoft\\WindowsFirewall\\{0}Profile\Logging" -f $LogProfile) + $localPath = [Environment]::ExpandEnvironmentVariables($RegKey.GetValue("LogFilePath")) + + # Set Remote Registry back the way we found it if we had to change it + + if($statusChanged) { + Write-Verbose ("Reverting status of $serviceName Service to {0}." -f $remoteRegistry.Status) + # Set-Service -Name $serviceName -ComputerName $ComputerName -Status $remoteRegistry.Status + # Need to use Invoke-Command as Set-Service won't stop a service that has dependencies + Invoke-Command -ComputerName $ComputerName -ScriptBlock { Stop-Service -Name "RemoteRegistry" } + + # Verify that service has been restored to its original state. + $revertedRemoteRegistry = Get-Service -Name $serviceName -ComputerName $ComputerName + if($remoteRegistry.Status -ne $revertedRemoteRegistry.Status) { + Write-Warning "Failed to revert $serviceName status to $($remoteRegistry.Status)!" + } + } + + if($startTypeChanged) { + Write-Verbose ("Reverting Startup of $serviceName Service to {0}." -f $remoteRegistry.StartType) + Set-Service -Name $serviceName -ComputerName $ComputerName -StartupType $remoteRegistry.StartType + + # Verify that service has been restored to its original state. + if($remoteRegistry.StartType -ne $revertedRemoteRegistry.StartType) { + Write-Warning "Failed to revert startup type of $serviceName to $($remoteRegistry.StartType)!" + } } } @@ -91,7 +108,9 @@ function Get-PSFirewallLogPath { $path = [Environment]::ExpandEnvironmentVariables((Get-ItemProperty -Path ("HKLM:\SOFTWARE\Policies\Microsoft\WindowsFirewall\{0}Profile\Logging" -f $LogProfile) -Name "LogFilePath").LogFilePath) if($null -eq $path) { - $path = "$ENV:SystemRoot\system32\LogFiles\Firewall\pfirewall.log" + $defaultPath = "$ENV:SystemRoot\system32\LogFiles\Firewall\pfirewall.log" + Write-Warning "Path for $LogProfile firewall log not defined in registry. Assuming default path of $defaultPath" + $path = $defaultPath } return $path From 64964b3de48efe1de8a6d22922167e3c8888dd62 Mon Sep 17 00:00:00 2001 From: Thumbscrew Date: Mon, 6 Jan 2020 15:07:44 +0000 Subject: [PATCH 2/2] Get-Help added. --- public/Get-PSFirewallLog.ps1 | 41 ++++++++++++++++++++++++++++++++ public/Get-PSFirewallLogPath.ps1 | 29 ++++++++++++++++++++++ 2 files changed, 70 insertions(+) diff --git a/public/Get-PSFirewallLog.ps1 b/public/Get-PSFirewallLog.ps1 index 188495e..a182ad0 100644 --- a/public/Get-PSFirewallLog.ps1 +++ b/public/Get-PSFirewallLog.ps1 @@ -1,4 +1,45 @@ function Get-PSFirewallLog { + <# + .SYNOPSIS + + Retrieves Windows Firewall log events and returns them as a table. + + .DESCRIPTION + + Retrieves Windows Firewall log events and returns them as a table. Log path can be directly specified or automatically determined based on local or remote registry settings. + + .EXAMPLE + + Get-PSFirewallLog -Path C:\Windows\system32\logfiles\firewall\pfirewall.log -Tail 1000 + + Get last 1000 Windows Firewall log lines at a specific path. + + .EXAMPLE + + Get-PSFirewallLog -LogDirectory C:\Windows\system32\logfiles\firewall\ -LogFileName domainfw.log + + Get Windows Firewall log by specifying the log directory and filename separately. + + .EXAMPLE + + Get-PSFirewallLog -LogProfile Domain + + Get Windows Firewall log by retrieving the path automatically from the registry on the local machine. + + .EXAMPLE + + Get-PSFirewallLog -LogProfile Public -ComputerName MyRemoteComputer -Verbose + + Get Windows Firewall log on a remote computer using the Remote Registry service to get the log path. + + .EXAMPLE + + Get-PSFirewallLog -LogProfile Public -ComputerName MyRemoteComputer -InferPath + + Get Windows Firewall log on a remote computer using the path configured in the local machine's registry (converted to a UNC path). + + #> + [CmdletBinding(DefaultParameterSetName = 'direct')] param ( # Path to firewall log. Defaults to $ENV:SystemRoot\system32\LogFiles\Firewall\pfirewall.log if parameter not supplied. diff --git a/public/Get-PSFirewallLogPath.ps1 b/public/Get-PSFirewallLogPath.ps1 index 3586942..8b64002 100644 --- a/public/Get-PSFirewallLogPath.ps1 +++ b/public/Get-PSFirewallLogPath.ps1 @@ -1,4 +1,33 @@ function Get-PSFirewallLogPath { + <# + .SYNOPSIS + + Retrieves Windows Firewall log path for a given Profile. + + .DESCRIPTION + + Retrieves Windows Firewall log path for a local or remote machine for given Profile. + + .EXAMPLE + + Get-PSFirewallLogPath -LogProfile Domain + + Retrieves path of the specified profile's log from the local machine. + + .EXAMPLE + + Get-PSFirewallLogPath -LogProfile Private -ComputerName MyRemoteComputer + + Retrieves path of the specified profile's log from a remote machine using the Remote Regsitry service. + + .EXAMPLE + + Get-PSFirewallLogPath -LogProfile Domain -ComputerName MyRemoteComputer -InferPath + + Retrieves path of the specified profile's log from a remote machine using registry settings configured on the local machine. + + #> + param( # Log Profile to retrieve path for [Parameter(Mandatory = $true)]