Skip to content

Commit 7e30c49

Browse files
committed
Asynchronus Port-Scan is working fine
1 parent 1dba159 commit 7e30c49

File tree

2 files changed

+177
-8
lines changed

2 files changed

+177
-8
lines changed

README.md

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,42 @@
11
# PowerShell-Async-PortScanner
2+
3+
Powerful asynchronus Port-Scanner which returns a custom PowerShell-Object with basic informations about the scanned Port-Range include Port and Status.
4+
5+
## Description
6+
7+
This is a powerful asynchronus Port-Scanner working with the PowerShell RunspacePool. You can scan any Port-Range you want.
8+
9+
This script also work fine along with my asychronus IP-Scanner published on GitHub too. You can easily pipe the output of the IP-Scanner result in this script.
10+
11+
## Syntax
12+
13+
```powershell
14+
.\ScanPortsAsync.ps1 [-IPv4Address] <IPAddress> [[-StartPort] <Int32>] [[-EndPort] <Int32>] [[-Threads] <Int32>] [[-IncludeClosed]] [<CommonParameters>]
15+
```
16+
17+
## Example
18+
19+
Simple Port Scan
20+
```powershell
21+
.\ScanPortsAsync.ps1 -IPv4Address 192.168.1.100 -StartPort 1 -EndPort 5000
22+
```
23+
24+
Show closed Ports in result
25+
```powershell
26+
.\ScanPortsAsync.ps1 -IPv4Address 172.16.2.5 -Threads 200 -IncludeClosed
27+
```
28+
29+
30+
## Output
31+
32+
Port Status
33+
---- ------
34+
21 Open
35+
80 Open
36+
139 Open
37+
443 Open
38+
445 Open
39+
40+
## ToDo
41+
- Integrate Port-List
42+
like: 80 (http), 443 (https) ...

ScanPortsAsync.ps1

Lines changed: 136 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,24 @@
88

99
<#
1010
.SYNOPSIS
11+
Powerful asynchronus Port-Scanner which returns a custom PowerShell-Object with basic informations about the
12+
scanned Port-Range include Port and Status.
1113
1214
.DESCRIPTION
15+
This is a powerful asynchronus Port-Scanner working with the PowerShell RunspacePool. You can scan any
16+
Port-Range you want.
17+
18+
This script also work fine along with my asychronus IP-Scanner published on GitHub too. You can easily
19+
pipe the output of the IP-Scanner result in this script.
20+
21+
If you found a bug or have some ideas to improve this script... Let me know. You find my Github profile in
22+
the links below.
1323
1424
.EXAMPLE
25+
.\ScanPortsAsync.ps1 -IPv4Address 172.16.0.1 -StartPort 1 -EndPort 1000
26+
27+
.EXAMPLE
28+
.\ScanPortsAsync.ps1 -IPv4Address 192.168.1.100 -IncludeClosed
1529
1630
.LINK
1731
Github Profil: https://github.com/BornToBeRoot
@@ -23,20 +37,32 @@ Param(
2337
[Parameter(
2438
Position=0,
2539
Mandatory=$true,
26-
HeldMessage='Enter IP-Address of the device which you want to scan')]
40+
HelpMessage='Enter IP-Address of the device which you want to scan')]
2741
[IPAddress]$IPv4Address,
2842

2943
[Parameter(
3044
Position=1,
3145
Mandatory=$false,
32-
HelpMessage='')]
46+
HelpMessage='Enter the Start-Port (Default=1)')]
3347
[Int32]$StartPort=1,
3448

3549
[Parameter(
3650
Position=2,
3751
Mandatory=$false,
38-
HelpMessage='Enter the Start Port')]
39-
[Int32]$EndPort=65535
52+
HelpMessage='Enter the End-Port (Default=65535)')]
53+
[Int32]$EndPort=65535,
54+
55+
[Parameter(
56+
Position=3,
57+
Mandatory=$false,
58+
HelpMessage='Set the maximum number of threads at the same time (Default=100)')]
59+
[Int32]$Threads=100,
60+
61+
[Parameter(
62+
Position=4,
63+
Mandatory=$false,
64+
HelpMessage='Show closed Ports in result')]
65+
[Switch]$IncludeClosed
4066
)
4167

4268
Begin{
@@ -49,20 +75,122 @@ Begin{
4975
# Validate Port-Range
5076
if($StartPort -gt $EndPort)
5177
{
52-
78+
Write-Host "Check your input! Invalid Port-Range... (-StartPort can't be lower than -EndPort)" -ForegroundColor Red
79+
exit
5380
}
5481

55-
# Some User-Output about the selected or default settings
82+
$PortRange = ($EndPort - $StartPort)
83+
84+
if(-not( Test-Connection -ComputerName $IPv4Address -Count 2 -Quiet))
85+
{
86+
Write-Host "IP-Address not reachable!" -ForegroundColor Red
87+
exit
88+
}
5689

90+
# Some User-Output about the selected or default settings
91+
Write-Host "`nScript ($ScriptFileName) started at $StartTime" -ForegroundColor Green
92+
Write-Host "`n+---------------------------------------Settings----------------------------------------`n|"
93+
Write-Host "| IP-Address:`t$IPv4Address"
94+
Write-Host "| Port-Range:`t$StartPort-$EndPort"
95+
Write-Host "| Threads:`t`t$Threads"
96+
Write-Host "|`n+---------------------------------------------------------------------------------------`n"
5797
}
5898

5999
Process{
100+
# Scriptblock that will run in runspaces (threads)...
101+
[System.Management.Automation.ScriptBlock]$ScriptBlock = {
102+
# Parameters
103+
$IPv4Address = $args[0]
104+
$Port = $args[1]
105+
106+
try{
107+
$Socket = New-Object System.Net.Sockets.TcpClient($IPv4Address,$Port)
108+
109+
if($Socket.Connected)
110+
{
111+
$Status = "Open"
112+
$Socket.Close()
113+
}
114+
}
115+
catch
116+
{
117+
$Status = "Closed"
118+
}
119+
120+
$Result = New-Object -TypeName PSObject
121+
Add-Member -InputObject $Result -MemberType NoteProperty -Name Port -Value $Port
122+
Add-Member -InputObject $Result -MemberType NoteProperty -Name Status -Value $Status
123+
return $Result
124+
}
60125

126+
# Setting up runspaces
127+
Write-Host "Setting up Runspace-Pool...`t`t" -ForegroundColor Yellow -NoNewline
128+
129+
$RunspacePool = [System.Management.Automation.Runspaces.RunspaceFactory]::CreateRunspacePool(1, $Threads, $Host)
130+
$RunspacePool.Open()
131+
$Jobs = @()
132+
133+
Write-Host "[" -ForegroundColor Gray -NoNewline; Write-Host "Done" -ForegroundColor Green -NoNewline; Write-Host "]" -ForegroundColor Gray
61134

62-
}
135+
#Setting up jobs
136+
Write-Host "Setting up jobs...`t`t`t" -ForegroundColor Yellow -NoNewline
63137

138+
foreach($Port in $StartPort..$EndPort)
139+
{
140+
if($PortRange -gt 0) { $Progress_Percent = (($Port - $StartPort) / $PortRange) * 100 } else { $Progress_Percent = 100 }
141+
Write-Progress -Activity "Setting up jobs..." -Id 1 -Status "Current Port: $Port" -PercentComplete ($Progress_Percent)
142+
143+
$Job = [System.Management.Automation.PowerShell]::Create().AddScript($ScriptBlock).AddArgument($IPv4Address).AddArgument($Port)
144+
$Job.RunspacePool = $RunspacePool
145+
$Jobs += New-Object psobject -Property @{
146+
RunNum = $Port - $StartPort
147+
Pipe = $Job
148+
Result = $Job.BeginInvoke()
149+
}
150+
}
64151

65-
End{
152+
Write-Host "[" -ForegroundColor Gray -NoNewline; Write-Host "Done" -ForegroundColor Green -NoNewline; Write-Host "]" -ForegroundColor Gray
153+
154+
# Wait until all Jobs are finished
155+
Write-Host "Waiting for jobs to complete...`t`t" -ForegroundColor Yellow -NoNewline
156+
157+
Do {
158+
Start-Sleep -Milliseconds 500
159+
160+
Write-Progress -Activity "Waiting for jobs to complete... ($($Threads - $($RunspacePool.GetAvailableRunspaces())) of $Threads threads running)" -Id 1 -PercentComplete (($Jobs.Count - $($($Jobs | Where-Object {$_.Result.IsCompleted -eq $false}).Count)) / $Jobs.Count * 100) -Status "$(@($($Jobs | Where-Object {$_.Result.IsCompleted -eq $false})).Count) remaining..."
161+
} While ($Jobs.Result.IsCompleted -contains $false)
162+
163+
Write-Host "[" -ForegroundColor Gray -NoNewline; Write-Host "Done" -ForegroundColor Green -NoNewline; Write-Host "]" -ForegroundColor Gray
164+
165+
Write-Host "Process results...`t`t`t" -ForegroundColor Yellow -NoNewline
66166

167+
# Built global array
168+
$Results = @()
67169

170+
# Get results and fill the array
171+
foreach($Job in $Jobs)
172+
{
173+
$Results += $Job.Pipe.EndInvoke($Job.Result)
174+
}
175+
176+
Write-Host "[" -ForegroundColor Gray -NoNewline; Write-Host "Done" -ForegroundColor Green -NoNewline; Write-Host "]" -ForegroundColor Gray
177+
}
178+
179+
180+
End{
181+
$EndTime = Get-Date
182+
183+
$ExecutionTimeMinutes = (New-TimeSpan -Start $StartTime -End $EndTime).Minutes
184+
$ExecutionTimeSeconds = (New-TimeSpan -Start $StartTime -End $EndTime).Seconds
185+
186+
# Some User-Output with Device UP/Down and execution time
187+
Write-Host "`n+----------------------------------------Result-----------------------------------------`n|"
188+
Write-Host "| Ports Open:`t`t$(@($Results | Where-Object {($_.Status -eq "Open")}).Count)"
189+
Write-Host "| Ports Closed:`t$(@($Results | Where-Object {($_.Status -eq "Closed")}).Count)"
190+
Write-Host "|`n+---------------------------------------------------------------------------------------`n"
191+
Write-Host "Script duration:`t$ExecutionTimeMinutes Minutes $ExecutionTimeSeconds Seconds`n" -ForegroundColor Yellow
192+
Write-Host "Script ($ScriptFileName) exit at $EndTime`n" -ForegroundColor Green
193+
194+
# Return custom psobject with Port status
195+
if($IncludeClosed) { return $Results } else { return $Results | Where-Object {$_.Status -eq "Open"} }
68196
}

0 commit comments

Comments
 (0)