Skip to main content

Follow-Up Work

Autodidactic Learning Time

Complete these videos on TCM Academy. Ask your peers (I'm happy to field questions as well) if you have any issues completing these lessons.

  • Sockets video
  • Reading/Writing Files video
  • Building a Port Scanner video
  • Building a Shoe Budget Tool video

Supplementary PowerShell Code

  • Just to stay consistent with the rest of today's lesson
  • TCM will show you how to do these things in Python, I'll show you the PowerShell way

Reading & Writing Files in PowerShell

PowerShell Code Example
$name = 'John Doe'
$favoriteFood = 'Pizza'
$todaysDate = Get-Date

# Create a dummy file
$pathToFile = "$env:UserProfile\Desktop\test-file.txt"
New-Item -ItemType File -Path $pathToFile | Out-Null

# Write contents to the dummy file
$contentsToWrite = @"
Hello! My name is $name
My favorite food is $favoriteFood
Today's date is $($todaysDate.ToShortDateString())
"@

# Overwrite the file
Out-File -FilePath $pathToFile -InputObject $contentsToWrite -Encoding UTF8 -Force

# Append to the end of the file
Out-File -FilePath $pathToFile -InputObject $contentsToWrite -Encoding UTF8 -Force -Append

# Retrieve the contents of the file
$fileContents = Get-Content $pathToFile
$fileContents

My TCP Port Scanner in PowerShell

  • It's definitely not the best TCP port scanner, but can serve as example code
  • Does not do UDP
  • I'm not a big fan of rewriting tools where better exist (e.g. nmap)
Test-TcpPort
function Test-TcpPort {

    [CmdletBinding()]
    param (
        [Parameter(
            Mandatory = $true,
            Position = 0,
            HelpMessage = 'Enter an IP address, hostname, or FQDN.'
        )]
        [String[]]
        $TargetHost,

        [Parameter(
            Mandatory = $true,
            Position = 1,
            HelpMessage = 'Enter a TCP port between 1 and 65535. It may be a single port, comma separated, or a range; or a combination.'
        )]
        [ValidateRange(1,65535)]
        [Int[]]
        $Port,

        [Parameter(Position = 2)]
        [ValidateRange(1,100)]
        [Int]
        $Threads = 10,

        [Parameter(Position = 3)]
        [ValidateRange(100,10000)]
        [Int]
        $TimeOutMilliseconds = 1000
    )
    begin {

        $jobs = @()
        $scriptBlock = {

            $target = $args[0]
            $ports = $args[1]
            $timeout = $args[2]

            $result = [PSCustomObject]@{
                'Target' = $target
                'Ports' = @()
            }

            $ports | ForEach-Object {

                $port = $_            
                $tcpClient = New-Object Net.Sockets.TcpClient
                if ($tcpClient.ConnectAsync($target, $port).Wait($timeout)) {
                    $state = 'Open'
                }
                else {
                    $state = 'Closed'
                }

                $result.Ports += [PSCustomObject]@{
                    'Protocol' = 'TCP'
                    'Port' = $port
                    'State' = $state
                }

                $tcpClient.Close()
                $tcpClient.Dispose()

            }
            return $result

        }

    }
    process {

        for ($i = 0; $i -le $TargetHost.Count; $i += $Threads) {
            
            $start = $i
            $end = ($i + $Threads) - 1
            $TargetHost[$start..$end] | ForEach-Object {
                $target = $_
                Write-Verbose "Processing host: $target"
                $jobs += Start-Job -Name $target -ScriptBlock $scriptBlock -ArgumentList $target, $Port, $TimeOutMilliseconds
            }
            $jobs | Wait-Job | Out-Null

        }

    }
    end {

        $jobs | Receive-Job | Select-Object -Property * -ExcludeProperty PSComputerName, PSShowComputerName, RunspaceId
        $jobs | Remove-Job -Force

    }
    
}

https://github.com/0xBEN/PSToolbox/blob/master/Public/ps1/Test-TcpPort.ps1