Compare commits

...

12 Commits
0.2 ... master

4 changed files with 224 additions and 111 deletions

Binary file not shown.

View File

@ -27,3 +27,11 @@ Get Windows Firewall log on a remote computer using the Remote Registry service
```powershell
Get-PSFirewallLog -LogProfile Public -ComputerName MyRemoteComputer -Verbose
```
Get the last 100 events from the Domain profile of a remote machine, inferring the path using the local machine's path (doesn't use Remote Registry service):
```powershell
Get-PSFirewallLog -LogProfile Domain -ComputerName MyRemoteComputer -InferPath -Tail 100
```
Get the last 100 events from the Private profile firewall log and follow the log:
```powershell
Get-PSFirewallLog -LogProfile Private -Tail 100 -Wait
```

View File

@ -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.
@ -23,24 +64,39 @@ function Get-PSFirewallLog {
[string]
$LogProfile,
# Number of firewall events to retrieve. Defaults to 0 (All events).
# Number of firewall events to retrieve. Defaults to -1 (All events).
[Parameter(Mandatory = $false)]
[int]
$Tail = 0,
$Tail = -1,
# ComputerName to retrieve log from
[Parameter(Mandatory = $true, ParameterSetName = 'remote')]
[string]
$ComputerName
$ComputerName,
# Follow the log
[Parameter(Mandatory = $false)]
[switch]
$Wait,
# Use local machine's registry setting to infer remote machine's log path
[Parameter(Mandatory = $false, ParameterSetName = 'remote')]
[switch]
$InferPath
)
begin {
if($PSCmdlet.ParameterSetName -eq 'auto') {
# $Path = [Environment]::ExpandEnvironmentVariables((Get-ItemProperty -Path ("HKLM:\SOFTWARE\Policies\Microsoft\WindowsFirewall\{0}Profile\Logging" -f $LogProfile) -Name "LogFilePath").LogFilePath)
$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
}
}
@ -59,17 +115,6 @@ function Get-PSFirewallLog {
}
if(Test-Path $logPath) {
$log = Get-Content $logPath
if($log.Length -gt 0) {
# Remove header lines
$log = $log[5..($log.Length - 1)]
if($Tail -gt 0) {
$startIndex = if($Tail -lt $log.Length) { $log.Length - $Tail } else { 0 }
$log = $log[$startIndex..($log.Length - 1)]
}
$members = @{
"Date" = 0
@ -91,8 +136,24 @@ function Get-PSFirewallLog {
"Path" = 16
}
$log | ForEach-Object {
$count = (Get-Content -Path $logPath).Count
# Check if outputting all events from the log and cut the first 5 lines that aren't events.
if(($Tail -lt 0) -or ($Tail -gt $count)) {
$Tail = $count - 5
}
Write-Verbose "Log has $count lines. Retrieving $Tail lines."
$c = "Get-Content -Path $logPath -Tail $Tail"
if($Wait) {
$c = "$c -Wait"
}
Invoke-Expression $c | ForEach-Object {
$line = $_
$split = $line -split ('\s')
$fwEvent = New-Object PSCustomObject
@ -106,10 +167,6 @@ function Get-PSFirewallLog {
$fwEvent
}
}
else {
Write-Error "File $logPath has zero length."
}
}
else {
Write-Error "Failed to retrieve log at $logPath."
}

View File

@ -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)]
@ -9,13 +38,29 @@ 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') {
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($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
@ -61,7 +106,7 @@ function Get-PSFirewallLogPath {
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 dependancies
# 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.
@ -80,6 +125,7 @@ function Get-PSFirewallLogPath {
Write-Warning "Failed to revert startup type of $serviceName to $($remoteRegistry.StartType)!"
}
}
}
# Do the conversion to UNC path
$path = "\\$ComputerName\" + $localPath.replace(':', '$')
@ -91,7 +137,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