Init commit

This commit is contained in:
James 2019-11-01 08:20:21 +00:00
commit 9befcdbdbd
7 changed files with 297 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
.vscode/

BIN
PSWinFW.psd1 Normal file

Binary file not shown.

14
PSWinFW.psm1 Normal file
View File

@ -0,0 +1,14 @@
# Get public and private function definition files.
$Public = @( Get-ChildItem -Path $PSScriptRoot\Public\*.ps1 -ErrorAction SilentlyContinue -Recurse )
$Private = @( Get-ChildItem -Path $PSScriptRoot\Private\*.ps1 -ErrorAction SilentlyContinue -Recurse )
# Dot source the files
Foreach ($import in @($Public + $Private)) {
Try {
. $import.fullname
} Catch {
Write-Error -Message "Failed to import function $($import.fullname): $_"
}
}
Export-ModuleMember -Function '*' -Alias '*'

29
README.md Normal file
View File

@ -0,0 +1,29 @@
# **PSWinFW (beta)**
**Note: Module is WIP. Testing is done in a domain environment (not sure how it will fair on standalone machines). Pull Requests welcome.**
## **Description**
A powershell module for retrieving Windows Firewall logs and displaying them in a nicer, more useful format.
## **Installation**
```
git clone https://github.com/Thumbscrew/PSWinFW.git
Import-Module PSWinFW\PSWinFW.psm1
```
## **Example Usage**
Get last 1000 Windows Firewall log lines at a specific path:
```powershell
Get-PSFirewallLog -Path C:\Windows\system32\logfiles\firewall\pfirewall.log -Tail 1000
```
Get Windows Firewall log by specifying the log directory and filename separately:
```powershell
Get-PSFirewallLog -LogDirectory C:\Windows\system32\logfiles\firewall\ -LogFileName domainfw.log
```
Get Windows Firewall log by retrieving the path automatically from the registry on the local machine:
```powershell
Get-PSFirewallLog -LogProfile Domain
```
Get Windows Firewall log on a remote computer using the Remote Registry service to get the log path:
```powershell
Get-PSFirewallLog -LogProfile Public -ComputerName MyRemoteComputer -Verbose
```

View File

@ -0,0 +1,148 @@
function Get-PSFirewallLog {
[CmdletBinding(DefaultParameterSetName = 'direct')]
param (
# Path to firewall log. Defaults to $ENV:SystemRoot\system32\LogFiles\Firewall\pfirewall.log if parameter not supplied.
[Parameter(Mandatory = $false, Position = 0, ValueFromPipeline, ParameterSetName = 'direct')]
[string]
$Path = "$ENV:SystemRoot\system32\LogFiles\Firewall\pfirewall.log",
# Path to firewall log directory. Defaults to $ENV:SystemRoot\system32\LogFiles\Firewall\ if parameter not supplied.
[Parameter(Mandatory = $false, ParameterSetName = 'indirect')]
[string]
$LogDirectory = "$ENV:SystemRoot\system32\LogFiles\Firewall\",
# Log file name.
[Parameter(Mandatory = $true, ParameterSetName = 'indirect')]
[string]
$LogFileName,
# Retrieve a profile's log using registry settings of the local machine
[Parameter(Mandatory = $true, ParameterSetName = 'auto')]
[Parameter(ParameterSetName = 'remote')]
[ValidateSet('Public','Private','Domain')]
[string]
$LogProfile,
# Number of firewall events to retrieve. Defaults to 0 (All events).
[Parameter(Mandatory = $false)]
[int]
$Tail = 0,
# Include extended TCP information (TCP Flags, TCP Sequence Number, TCP ACK Number, TCP Window Size). Defaults to false.
[Parameter(Mandatory = $false)]
[switch]
$IncludeTcpInfo,
# Include extended ICMP information (ICMP Type and Code). Defaults to false.
[Parameter(Mandatory = $false)]
[switch]
$IncludeIcmpInfo,
# Include Info field. Defaults to false.
[Parameter(Mandatory = $false)]
[switch]
$IncludeInfo,
# ComputerName to retrieve log from
[Parameter(Mandatory = $false, ParameterSetName = 'remote')]
[string]
$ComputerName
)
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
}
}
process {
if($PSCmdlet.ParameterSetName -eq 'indirect') {
# Check for trailing slash and add if necessary
if(!$LogDirectory.EndsWith('\')) {
$LogDirectory += '\'
}
$logPath = $LogDirectory + $LogFileName
}
else {
$logPath = $Path
}
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
"Time" = 1
"Action" = 2
"Protocol" = 3
"SourceIP" = 4
"DestinationIP" = 5
"SourcePort" = 6
"DestinationPort" = 7
"Size" = 8
}
if($IncludeTcpInfo) {
$tcpMembers = @{
"TcpFlags" = 9
"TcpSyn" = 10
"TcpAck" = 11
"TcpWin" = 12
}
$members += $tcpMembers
}
if($IncludeIcmpInfo) {
$icmpMembers = @{
"IcmpType" = 13
"IcmpCode" = 14
}
$members += $icmpMembers
}
if($IncludeInfo) {
$members += @{ "Info" = 15 }
}
$members += @{ "Path" = 16 }
$log | ForEach-Object {
$line = $_
$split = $line -split ('\s')
$fwEvent = New-Object PSCustomObject
foreach($member in $members.GetEnumerator() | Sort-Object Value) {
$fwEvent | Add-Member NoteProperty -Name $member.Name -Value $split[$member.Value]
}
$fwEvent
}
}
else {
Write-Error "File $logPath has zero length."
}
}
else {
Write-Error "Failed to retrieve log at $logPath."
}
}
}

View File

@ -0,0 +1,100 @@
function Get-PSFirewallLogPath {
param(
# Log Profile to retrieve path for
[Parameter(Mandatory = $true)]
[ValidateSet('Public','Private','Domain')]
[string]
$LogProfile,
# Remote Host to retrieve from
[Parameter(Mandatory = $false, ParameterSetName = 'remote')]
[string]
$ComputerName
)
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($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 dependancies
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)!"
}
}
# Do the conversion to UNC path
$path = "\\$ComputerName\" + $localPath.replace(':', '$')
return $path
}
else {
# Get local registry key entry
$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"
}
return $path
}
}
}

5
tests/PathRetrieval.ps1 Normal file
View File

@ -0,0 +1,5 @@
Import-Module .\PSWinFW.psm1 -Force
$path = Get-PSFirewallLogPath -LogProfile Public -ComputerName stb603970 -Verbose
Write-Host $path