PSGraphPlus.psm1
Write-Verbose 'Importing from [C:\projects\psgraphplus\PSGraphPlus\private]' Write-Verbose 'Importing from [C:\projects\psgraphplus\PSGraphPlus\public]' # .\PSGraphPlus\public\Show-GitGraph.ps1 function Show-GitGraph { <# .SYNOPSIS Gets a graph of the git history .DESCRIPTION This will generate a graph showing the recent histroy of a project with the branches. .PARAMETER Path Local location of the Git repository .PARAMETER HistoryDepth How far back into history to show .PARAMETER Uri Allows the injection of a base URL for github projects .PARAMETER ShowCommitMessage This will show the git commit instead of the hash .PARAMETER Raw Output the raw graph without generating the image or showing it. Useful for testing. .EXAMPLE Show-GitGraph .EXAMPLE Show-GitGraph -HistoryDepth 30 .EXAMPLE Show-GitGraph -Path c:\workspace\project -ShowCommitMessage .NOTES #> [CmdletBinding()] param( $Path = $PWD, [alias('Depth')] $HistoryDepth = 15, $Uri = 'https://github.com/KevinMarquette/PSGraph', [switch] $ShowCommitMessage, [switch] $Raw ) process { Push-Location $Path # Git history with branch details $git = git log --format="%h|%p|%s" -n $HistoryDepth --branches=* | Select-Object -SkipLast 1 $HASH = 0 $PARENT = 1 $SUBJECT = 2 $branches = git branch -a -v if ($ShowCommitMessage) { $labelIndex = $SUBJECT } else { $labelIndex = $HASH } $graph = graph git @{ rankdir = 'LR'; label = [regex]::Escape( $PWD) } { Node @{shape = 'box'} foreach ($line in $git) { $data = $line.split('|') Node -Name $data[$HASH] @{ label = $data[$labelIndex] URL = "{0}/commit/{1}" -f $Uri, $data[$HASH] } Edge -From $data[$PARENT].split(' ') -To $data[$HASH] } Node @{shape = 'box'; fillcolor = 'green'; style = 'filled'} foreach ($line in $branches) { if ($line -match '(?<branch>[\w/-]+)\s+(?<hash>\w+) (.+)') { Node $Matches.branch Edge $Matches.branch -From $Matches.hash } } } if ($Raw) { $graph } else { $graph | Export-PSGraph -ShowGraph } Pop-Location } } # .\PSGraphPlus\public\Show-NetworkConnectionGraph.ps1 function Show-NetworkConnectionGraph { <# .SYNOPSIS Generates a map of network connections .Description This graph will show the source and target IP addresses with each edge showing the ports .EXAMPLE Show-NetworkConnectionGraph .Example Show-NetworkConnectionGraph -ComputerName $server -Credential $Credential .NOTES #> [CmdletBinding( DefaultParameterSetName = 'Default' )] param( # Remote computer name [Parameter( ParameterSetName = 'Default' )] [string[]] $ComputerName, # Credential for authorization [Parameter( ParameterSetName = 'Default' )] [pscredential] $Credential, # Outputs the raw dot graph (for testing [switch] $Raw ) process { $session = @{} if ( $null -ne $ComputerName -and $Credential ) { $PSBoundParameters.Remove('Raw') $session = @{ CimSession = New-CimSession @PSBoundParameters } } elseif ( $CimSession ) { $session = @{ CimSession = $CimSession } } $netstat = Get-NetTCPConnection -State Established, TimeWait -ErrorAction SilentlyContinue @session $netstat = $netstat | Where-Object LocalAddress -NotMatch ':' $dns = Get-DnsClientCache @session | Where-Object data -in $netstat.RemoteAddress $graph = graph network @{rankdir = 'LR'; label = 'Network Connections'} { Node @{shape = 'rect'} $EdgeParam = @{ Node = $netstat FromScript = {$_.LocalAddress} ToScript = {$_.RemoteAddress} Attributes = @{label = {'{0}:{1}' -f $_.LocalPort, $_.RemotePort}} } Edge @EdgeParam Node $dns -NodeScript {$_.data} @{label = {'{0}\n{1}' -f $_.entry, $_.data}} } if ($Raw) { $graph } else { $graph | Export-PSGraph -ShowGraph } } } # .\PSGraphPlus\public\Show-ProcessConnectionGraph.ps1 function Show-ProcessConnectionGraph { <# .SYNOPSIS Generates a map of network connections .Description This graph will show the source and target IP addresses with each edge showing the ports .EXAMPLE Show-NetworkConnectionGraph .Example Show-NetworkConnectionGraph -ComputerName $server -Credential $Credential .NOTES #> [CmdletBinding( DefaultParameterSetName = 'Default' )] param( # Remote computer name [Parameter( ParameterSetName = 'Default' )] [string[]] $ComputerName, # Credential for authorization [Parameter( ParameterSetName = 'Default' )] [pscredential] $Credential, # Outputs the raw dot graph (for testing) [switch] $Raw ) process { $session = @{} if ( $null -ne $ComputerName -and $Credential ) { $PSBoundParameters.Remove('Raw') $session = @{ CimSession = New-CimSession @PSBoundParameters } } $netstat = Get-NetTCPConnection -State Established, TimeWait -ErrorAction SilentlyContinue @session $netstat = $netstat | Where-Object LocalAddress -NotMatch ':' $dns = Get-DnsClientCache @session | Where-Object data -in $netstat.RemoteAddress $process = Get-CIMInstance -ClassName CIM_Process @session | Where-Object ProcessId -in $netstat.OwningProcess $graph = graph network @{rankdir = 'LR'; label = 'Process Network Connections'} { Node @{shape = 'rect'} Node $process -NodeScript {$_.ProcessID} @{label = {'{0}\n{1}' -f $_.ProcessName, $_.ProcessID}} $EdgeParam = @{ Node = $netstat FromScript = {$_.OwningProcess} ToScript = {$_.RemoteAddress} Attributes = @{label = {'{0}:{1}' -f $_.LocalPort, $_.RemotePort}} } Edge @EdgeParam Node $dns -NodeScript {$_.data} @{label = {'{0}\n{1}' -f $_.entry, $_.data}} } if ($Raw) { $graph } else { $graph | Export-PSGraph -ShowGraph } } } # .\PSGraphPlus\public\Show-ServiceDependencyGraph.ps1 function Show-ServiceDependencyGraph { <# .SYNOPSIS Show the process dependency graph .DESCRIPTION Loads all processes and maps out the dependencies .EXAMPLE Show-ProcessDependencyGraph .NOTES General notes #> [CmdletBinding()] param( # Service Name [Parameter()] [string[]] $Name, # Remote computer name [Parameter()] [string[]] $ComputerName, # Credential for authorization [Parameter()] [pscredential] $Credential, # Outputs the raw dot graph (for testing) [switch] $Raw ) process { if ( $null -ne $ComputerName -and $Credential ) { Write-Verbose 'Connecting to remote system' $PSBoundParameters.Remove('Raw') $services = Invoke-Command @PSBoundParameters -ScriptBlock {Get-Service -Include *} } else { $services = Get-Service -Include * } if ($null -ne $Name) { Write-Verbose ( 'Filtering on name [{0}]' -f ( $Name -join ',' ) ) $services = foreach ($node in $services) { if ($node.Name -in $Name) { $node continue } foreach ($dependency in $node.ServicesDependedOn.Name) { if ( $dependency -in $Name) { $node continue } } } } if ( $null -eq $services ) { return } Set-NodeFormatScript {$_.tolower()} $graph = graph services @{rankdir = 'LR'} { Node @{shape = 'box'} Node $services -NodeScript {$_.name} @{ label = {'{0}\n{1}' -f $_.DisplayName, $_.Name} color = {If ($_.Status -eq 'Running') {'blue'}else {'red'}} } $linkedServices = $services | Where-Object {$_.ServicesDependedOn} Edge $linkedServices -FromScript {$_.Name} -ToScript {$_.ServicesDependedOn.Name} } Set-NodeFormatScript if ($Raw) { $graph } else { $graph | Export-PSGraph -ShowGraph } } } Write-Verbose 'Importing from [C:\projects\psgraphplus\PSGraphPlus\classes]' |