It is necessary that the results of the port scan are output to $TextBoxResultScan. If the port is open, the result is output, although not in the form that I would like. But if the port is closed, then the whole script freezes and the form too.
Why is the form and script hanging and how to fix it?
How to configure the output by columns, where the first column is the server address, the second column is the port number, the third column is the scan result.
Script Below.
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
<#------======== Define Variables ========------#>
$MyForest = ([System.DirectoryServices.ActiveDirectory.Forest]::GetCurrentForest()).Name
$MyDomain = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().Name
$NetworkPorts = @('21','22','23','25','38','42','53','65','69','80','118','123','135','137','139','143','145','156','161','170','389','443','445','647','993','995','1433','1540','1541','3389','8080')
<#------======== Define Variables ========------#>
<#------======== Common Form ========------#>
$CommonForm = New-Object System.Windows.Forms.Form
$CommonForm.AutoSize = $true
$CommonForm.Text = "Servers Scanning"
<#------======== Common Form ========------#>
<#------======== Label List Enable Servers ========------#>
$LabelListeServers = New-Object System.Windows.Forms.Label
$LabelListeServers.Location = '2,10'
$LabelListeServers.AutoSize = $true
$LabelListeServers.Text = 'Enable Servers Scanning'
$CommonForm.Controls.Add($LabelListeServers)
<#------======== Label List Enable Servers ========------#>
<#------======== ListBox List Enable Servers ========------#>
$ListboxListeServers = New-Object System.Windows.Forms.ListBox
$ListboxListeServers.Location = '2,30'
$ListboxListeServers.Size = New-Object System.Drawing.Size(200,125)
$CommonForm.Controls.Add($ListboxListeServers)
<#------======== ListBox List Enable Servers ========------#>
<#------======== Button Search Enable Servers ========------#>
$ButtonSearcheServers = New-Object System.Windows.Forms.Button
$ButtonSearcheServers.Location = '2, 165'
$ButtonSearcheServers.Text = 'Find Servers'
$ButtonSearcheServers.AutoSize = $true
$ButtonSearcheServers.add_Click({
$eADWindowsServers = @((Get-ADComputer -Server $MyDomain -Filter {(OperatingSystem -like '*Windows Server*') -and (Enabled -eq $true)} | sort Name).DnsHostName)
Foreach($eADWindowsServer in $eADWindowsServers){
$ListboxListeServers.Items.Add($eADWindowsServer)
}
})
$CommonForm.Controls.Add($ButtonSearcheServers)
<#------======== Button Search Enable Servers ========------#>
<#------======== Label List Disable Servers ========------#>
$LabelListdServers = New-Object System.Windows.Forms.Label
$LabelListdServers.Location = '2,195'
$LabelListdServers.AutoSize = $true
$LabelListdServers.Text = 'Disable Servers Scanning'
$CommonForm.Controls.Add($LabelListdServers)
<#------======== Label List Disable Servers ========------#>
<#------======== ListBox List Disable Servers ========------#>
$ListboxListdServers = New-Object System.Windows.Forms.ListBox
$ListboxListdServers.Location = '2,220'
$ListboxListdServers.Size = New-Object System.Drawing.Size(195,125)
$CommonForm.Controls.Add($ListboxListdServers)
<#------======== ListBox List Disable Servers ========------#>
<#------======== Button Search Disable Servers ========------#>
$ButtonSearchdServers = New-Object System.Windows.Forms.Button
$ButtonSearchdServers.Location = '2, 350'
$ButtonSearchdServers.Text = 'Find Servers'
$ButtonSearchdServers.AutoSize = $true
$ButtonSearchdServers.add_Click({
$dADWindowsServers = @((Get-ADComputer -Server $MyDomain -Filter {(OperatingSystem -like '*Windows Server*') -and (Enabled -eq $false)} | sort Name).DnsHostName)
Foreach($dADWindowsServer in $dADWindowsServers){
$ListboxListdServers.Items.Add($dADWindowsServer)
}
})
$CommonForm.Controls.Add($ButtonSearchdServers)
<#------======== Button Search Disable Servers ========------#>
<#------======== Label Port Scan ========------#>
$LabelPortScan = New-Object System.Windows.Forms.Label
$LabelPortScan.Location = '225,10'
$LabelPortScan.AutoSize = $true
$LabelPortScan.Text = 'Ports scanning. Port:'
$CommonForm.Controls.Add($LabelPortScan)
<#------======== Label Port Scan ========------#>
<#------======== ListBox Port Scan ========------#>
$TextBoxResultScan = New-Object System.Windows.Forms.TextBox
$TextBoxResultScan.Location = '225,30'
$TextBoxResultScan.Size = '565,200'
$TextBoxResultScan.Multiline = $true
$CommonForm.Controls.Add($TextBoxResultScan)
<#------======== ListBox Port Scan ========------#>
<#------======== TextBox Enter Port ========------#>
$TextBoxPortScan = New-Object System.Windows.Forms.TextBox
$TextBoxPortScan.Location = '360,7'
$TextBoxPortScan.Size = New-Object System.Drawing.Size(40,5)
$CommonForm.Controls.Add($TextBoxPortScan)
<#------======== TextBox Enter Port ========------#>
<#------======== Button Port Scan ========------#>
$ButtonPortScan = New-Object System.Windows.Forms.Button
$ButtonPortScan.Location = '400, 5'
$ButtonPortScan.Text = 'Check'
$ButtonPortScan.AutoSize = $true
$ButtonPortScan.add_Click({
if ($ListboxListeServers.SelectedItem -eq $null){
Foreach ($eADWindowsServer in $eADWindowsServers) {
Foreach ($NetworkPort in $NetworkPorts) {
$Result = Test-NetConnection -ComputerName $eADWindowsServer -Port $NetworkPort -ErrorAction SilentlyContinue -WarningAction SilentlyContinue
$TextBoxResultScan.Text = $Result | Select-Object @{Name='Host Address';Expression ={$_.RemoteAddress}}, @{Name = 'Port';Expression ={$_.RemotePort}}, @{Name = 'Port Status';Expression = {$_.TcpTestSucceeded}}
}
}
}
elseif (($ListboxListeServers.SelectedItem -ne $null) -and ($TextBoxPortScan.Text -eq '')){
$SelectedServer = $ListboxListeServers.SelectedItem.ToString()
foreach ($NetworkPort in $NetworkPorts){
$Result = Test-NetConnection -ComputerName $SelectedServer -Port $NetworkPort -ErrorAction SilentlyContinue -WarningAction SilentlyContinue
$TextBoxResultScan.Text = $Result | Select-Object @{Name='Host Address';Expression ={$_.RemoteAddress}}, @{Name = 'Port';Expression ={$_.RemotePort}}, @{Name = 'Port Status';Expression = {$_.TcpTestSucceeded}}
}
}
elseif (($ListboxListeServers.SelectedItem -ne $null) -and ($TextBoxPortScan.Text -ne '')){
$SelectedServer = $ListboxListeServers.SelectedItem
$SelectedPort = $TextBoxPortScan.Text
$Result = Test-NetConnection -ComputerName $SelectedServer -Port $SelectedPort -ErrorAction SilentlyContinue -WarningAction SilentlyContinue
$TextBoxResultScan.Text = $Result | Select-Object @{Name='Host Address';Expression ={$_.RemoteAddress}}, @{Name = 'Port';Expression ={$_.RemotePort}}, @{Name = 'Port Status';Expression = {$_.TcpTestSucceeded}}
}
})
$CommonForm.Controls.Add($ButtonPortScan)
<#------======== Button Port Scan ========------#>
<#------======== Call Form ========------#>
$CommonForm.ShowDialog()
<#------======== Call Form ========------#>
Try to your code to separated runspace such as using start-job command. Like :
Start-Job -Name "YourFormJob" {
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.Application]::EnableVisualStyles();
[System.Windows.Forms.Application]::SetCompatibleTextRenderingDefault($false);
$frm=New-Object System.Windows.Forms.Form -Property @{Text="Sample";Dock="Fill"};
$pnl=New-Object System.Windows.Forms.TableLayoutPanel -Property @{ColumnCount=1;RowCount=2};
$txt=New-Object System.Windows.Forms.TextBox -Property @{Text="Enter your text here";};
$btn=New-Object System.Windows.Forms.Button -Property @{Text="OK";};
###Copy your code above to here ##
$job=Start-Job -Name YouFreezingTask -ScriptBlock { sleep -Seconds 20; <# Send Some Results #>; 1..20 };
$btn.add_click({ $frm.Close(); });
$pnl.Controls.Add($txt);
$pnl.Controls.Add($btn);
$frm.Controls.Add($pnl);
$frm.add_shown({
$frm.Activate();
$txt.Text=$job.State;
while($job.State -match "Running")
{
[System.Windows.Forms.Application]::DoEvents();
sleep -Milliseconds 100;
};
$txt.Text=$job.State;
})
[void]$frm.ShowDialog();
# Passing back any results below:
echo $txt.Text
}
Please note that I've used the sleep command to simulate the heavy job that will freeze for 20 seconds.
The result of the TextBox should contains 'Running' till the it finished then will be 'Completed'
To receive the results from PowerShell Console:
gjb YourFormJob|rcjb;