Skip to content

Instantly share code, notes, and snippets.

@johnathanmay
Last active February 16, 2022 18:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save johnathanmay/c83e3fc26d70ed6b7b6b99396740a80e to your computer and use it in GitHub Desktop.
Save johnathanmay/c83e3fc26d70ed6b7b6b99396740a80e to your computer and use it in GitHub Desktop.

Common Powershell Commands

PowerShell Basics

#list powershell version and installed modules 
Get-Host | Select-Object Version
$PSVersionTable.PSVersion
Get-InstalledModule

#bypass execution policy to run script
powershell.exe -executionpolicy bypass .\script.ps1
Get-Content .\script.ps1 | powershell.exe -noprofile -

#create credential object
$cred = Get-Credential

#aliases to avoid when scripting and what to use instead
cd = Set-Location
ls = Get-ChildItem
gci = Get-ChildItem
mv = Move-Item
rm = Remove-Item

#grep output
command | findstr -i "string"
#new-alias grep findstr
#command | grep "string"

#check variable type
$var.GetType()

#create array
$array = @()

#append to array (actually creates new array with value added at end)
$array += "value"

#search array
$array -contains "value"

#sort array
$array = $array | Sort-Object

#remove items from array - create new one
$no_dcu_workstations = @()
foreach ($row in $no_dcu_list) {
    if ($row -notlike "ORG*") {
        $no_dcu_workstations += $row
    }
}

#generate current timestamp
Get-Date -Format yyyyMMddHHmm
$timestamp = Get-Date -Format yyyyMMddHHmmss
$date = Get-Date -Format yyyyMMdd

Environment Variables

#list all environment variables
ls env:
dir env:
gci env:
Get-ChildItem env:

#update environment variable just for session
#https://stackoverflow.com/questions/714877/setting-windows-powershell-environment-variables
$env:Path += ";C:\Program Files\GnuWin32\bin"

#set environment variable persistently
[System.Environment]::SetEnvironmentVariable('ResourceGroup','AZ_Resource_Group')
$new_path = $env:Path += ";C:\Program Files (x86)\Vim\vim82"
[System.Environment]::SetEnvironmentVariable('Path',$new_path)

#split path environment variable into human readable lines
$env:path -split ';'

#update environment variable persistently (across reboots)
[Environment]::SetEnvironmentVariable("Path", $env:Path +";C:\Program Files\7-zip\", [System.EnvironmentVariableTarget]::Machine)
[Environment]::SetEnvironmentVariable("Path", $env:Path + ";C:\utils", "Machine")
[Environment]::SetEnvironmentVariable("INCLUDE", $env:INCLUDE, [System.EnvironmentVariableTarget]::User)
[Environment]::SetEnvironmentVariable("Path", $env:Path + ";%userprofile%\.local\bin", "User")

Loops

#foreach loop
$numbers=1,2,3,4,5
foreach ($num in $numbers) {
  $num;
}

#hash table loop
$software = @{
    'PowerShell-7.1.3-win-x64.msi' = 'https://github.com/PowerShell/PowerShell/releases/download/v7.1.3/PowerShell-7.1.3-win-x64.msi';
    'Microsoft.WindowsTerminal_1.9.1942.0_8wekyb3d8bbwe.msixbundle' = 'https://github.com/microsoft/terminal/releases/download/v1.9.1942.0/Microsoft.WindowsTerminal_1.9.1942.0_8wekyb3d8bbwe.msixbundle';
    '7z2103-x64.exe' = 'https://www.7-zip.org/a/7z2103-x64.exe';
}
foreach($app in software.Keys) {
    Invoke-WebRequest -Uri $software.$app -OutFile "c:\utils\tmp\$app"
}

Strings

#split string into an array based on specific character
$str = Get-Content .\anaconda_users_shared_folder.csv |findstr -i "aawet"
$arr = $str.split('\\')

#get filename after last backslash
$filename.Split('\')[-1]

#remove / replace character in string
$str -replace '"',''

Computer and Operating System Info

#check last boot time on a server
Get-CimInstance -ClassName win32_operatingsystem -ComputerName $pc | select csname, lastbootuptime

#get os version of remote computer
Get-WmiObject Win32_OperatingSystem -ComputerName "comp_name" | Select-Object PSComputerName, Caption, OSArchitecture, Version, BuildNumber

#get serial number of PC
Get-CimInstance -ComputerName pc_name win32_bios |Select-Object SerialNumber
Get-WmiObject win32_bios | select Serialnumber

#windows server initial security checklist
Get-WindowsFeature | Where-Object {$_.Installed -eq "True"}
Get-SmbShare #check for non-essential
Get-SmbShare | Get-SmbShareAccess #check for non-essential Full rights
Get-LocalUser #check for non-essential
Get-LocalGroupMember Administrators #check for non-essential
Get-NetTCPConnection #or "netstat -an" or "netstat -ban"
Get-CimInstance Win32_StartupCommand | Select-Object Name, command, Location, User
Get-Item -Path 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Run'
Get-Item -Path 'HKLM:\Software\Microsoft\Windows\CurrentVersion\RunOnce'
Get-Item -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Run'
Get-Item -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\RunOnce'
Get-WmiObject -Class Win32_Product | Select-Object Vendor, Name, Version |ft
Get-WmiObject -Class Win32_Product | Where-Object {$_.Vendor | Select-String -notmatch "Microsoft Corporation","Intel Corporation"} | Select-Object Vendor, Name, Version |ft

Admin Tools

#list installed admin tools
Get-WindowsCapability -Name RSAT* -Online | Select-Object -Property State, Name, DisplayName

#install admin tools
Add-WindowsCapability -Name "Rsat.ActiveDirectory*" -Online
Get-WindowsCapability -Name RSAT* -Online | Add-WindowsCapability -Online

#list Windows Optional Features
Get-WindowsOptionalFeature -Online | Select-Object FeatureName, State

#install windows feature
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V -All -NoRestart

Bitlocker

#bitlocker encrypt system volume
$bitlocker_encrypt = Invoke-Command -ComputerName $workstations -ScriptBlock { Enable-BitLocker -MountPoint $env:SystemDrive -RecoveryPasswordProtector }

#bitlocker check status of D: drive 
$bitlocker_status = Invoke-Command -ComputerName $workstations -ScriptBlock { Get-BitLockerVolume -MountPoint "D:" }
$bitlocker_reboots = Invoke-Command -ComputerName $workstations -ScriptBlock { 
  $bl_status = Get-BitLockerVolume -MountPoint $env:SystemDrive
  if ($bl_status.ProtectionStatus -eq "Off") {
    shutdown -r -f -t 0
  }
  return $bl_status
}

Disks

#check disk used space of a folder (du -s ./)
$target_folder = 'c:\utils'
"{0:N2} GB" -f ((Get-ChildItem $target_folder -Recurse | Measure-Object -Property Length -Sum -ErrorAction Stop).Sum / 1GB)

#check disk space and last modified details for subfolders
$target_folder = 'c:\utils'
$data_coll = @()
Get-ChildItem -force $target_folder -ErrorAction SilentlyContinue | ? { $_ -is [io.directoryinfo] } | % {
    $len = 0
    Get-ChildItem -recurse -force $_.fullname -ErrorAction SilentlyContinue | % { $len += $_.length }
    $folder_name = $_.fullname
    $folder_size = '{0:N2}' -f ($len / 1Gb)
    $creation_time = $_.CreationTime
    $last_access_time = $_.LastAccessTime
    $last_write_time = $_.LastWriteTime
    $data_object = New-Object PSObject
    Add-Member -inputObject $data_object -memberType NoteProperty -name "folder_name" -value $folder_name
    Add-Member -inputObject $data_object -memberType NoteProperty -name "folder_size_Gb" -value $folder_size
    Add-Member -inputObject $data_object -memberType NoteProperty -name "creation_time" -value $creation_time
    Add-Member -inputObject $data_object -memberType NoteProperty -name "last_access_time" -value $last_access_time
    Add-Member -inputObject $data_object -memberType NoteProperty -name "last_write_time" -value $last_write_time
    $data_coll += $data_object
}
$data_coll | Out-GridView -Title "Folder Details"
$data_coll | Export-Csv -NoTypeInformation .\20210805-folder-details.csv

#get disk space details in GB on a server
# Get-WmiObject -Class Win32_LogicalDisk | ? {$_. DriveType -eq 3} | select DeviceID, {$_.Size /1GB}, @{n="FreeSpace";e={[math]::Round($_.FreeSpace/1GB,2)}, @{n="UsedSpace";e={[math]::Round(($_.Size - $_.FreeSpace)/1GB,2)}}}
Get-WmiObject -Class Win32_LogicalDisk | ? {$_. DriveType -eq 3} | select DeviceID, {$_.Size /1GB}, @{n="FreeSpace";e={[math]::Round($_.FreeSpace/1GB,0)}}, @{n="UsedSpace";e={[math]::Round(($_.Size - $_.FreeSpace)/1GB,0)}}

Invoke-Command -ComputerName $server_list -ScriptBlock {
    Get-WmiObject -Class Win32_LogicalDisk | ? {$_. DriveType -eq 3} | select DeviceID, {$_.Size /1GB}, @{n="FreeSpace";e={[math]::Round($_.FreeSpace/1GB,0)}}, @{n="UsedSpace";e={[math]::Round(($_.Size - $_.FreeSpace)/1GB,0)}}
}

foreach ($server in $server_list) {
    Get-WmiObject -Class Win32_LogicalDisk -ComputerName $server | ? {$_. DriveType -eq 3} | Where-Object {$_.DeviceID -like "C*"} | Select-Object @{Name="Name"; Expression={$server}}, DeviceID, {$_.Size /1GB}, {$_.FreeSpace /1GB}
}

Get-Volume
Get-Volume |Where-Object {$_.DriveLetter -eq "C"} |Select-Object {$_.SizeRemaining /1GB}

#get total disk space - capacity and amount used on a machine
Invoke-Command -ComputerName $server_list -ScriptBlock {
    $disks = Get-WmiObject -Class Win32_LogicalDisk | ? {$_. DriveType -eq 3} | select DeviceID, @{n="disk_size";e={[math]::Round($_.Size /1GB,0)}}, @{n="FreeSpace";e={[math]::Round($_.FreeSpace/1GB,0)}}, @{n="UsedSpace";e={[math]::Round(($_.Size - $_.FreeSpace)/1GB,0)}}
    foreach ($d in $disks) {
        $total_disk_used += $d.UsedSpace
        $total_disk_capacity += $d.disk_size
    }
    $obj_properties = @{ total_disk_capacity = "$total_disk_capacity"; total_disk_used = "$total_disk_used"}
    New-Object PsObject -Property $obj_properties
}

Files

#if path exists
if (Test-Path -Path $Folder) {
    "Path exists!"
} else {
    "Path doesn't exist."
}

#download file from URL (wget)
Invoke-WebRequest [-UseBasicParsing] -Uri <source> -OutFile <destination>

#unblock file downloaded from Internet
Unblock-File -Path .\file -Confirm:$false

#unzip files
Get-Command -Module Microsoft.PowerShell.Archive
ExpandArchive -Path 'c:\utils\tmp\MobaXterm_Portable_v21.2.zip' -DestinationPath 'c:\utils\'
Expand-Archive file.zip

#recursively delete folder
Remove-Item -Recurse -Force .\tmp

#get last modified date of folder
$(Get-ChildItem c:\temp).LastWriteTime

#copy file
Copy-Item source destination

#create shortcut (requires powershell 5+)
#https://stackoverflow.com/questions/9701840/how-to-create-a-shortcut-using-powershell
$WshShell = New-Object -comObject WScript.Shell
$Shortcut = $WshShell.CreateShortcut("$env:appdata\Microsoft\Windows\Start Menu\Programs\Windows Terminal.lnk")
$Shortcut.TargetPath = "C:\utils\WindowsTerminal\WindowsTerminal.exe"
$Shortcut.Save()

#create run as admin shortcut
$WshShell = New-Object -comObject WScript.Shell
$Shortcut = $WshShell.CreateShortcut("$env:appdata\Microsoft\Windows\Start Menu\Programs\Windows Terminal (Admin).lnk")
$Shortcut.TargetPath = "C:\utils\WindowsTerminal\WindowsTerminal.exe"
$Shortcut.Save()
$file="$env:appdata\Microsoft\Windows\Start Menu\Programs\Windows Terminal (Admin).lnk"
$bytes = [System.IO.File]::ReadAllBytes($file)
$bytes[0x15] = $bytes[0x15] -bor 0x20 #set byte 21 (0x15) bit 6 (0x20) ON (Use -bor to set RunAsAdministrator option and -bxor to unset)
[System.IO.File]::WriteAllBytes($file, $bytes)

#create symbolic link
New-Item -ItemType SymbolicLink -Path "C:\temp" -Name "calc.lnk" -Value "c:\windows\system32\calc.exe"

#create multiple 2GB random files
$out = new-object byte[] 2048000000; (New-Object System.Random).NextBytes($out); 
for ($i=1; $i -le $var_count; $i++) {[IO.File]::WriteAllBytes("C:\utils\tmp\jmtestfile$i.txt", $out)}

#get detailed file properties including DLL version
$pc = "pc_name"
[System.Diagnostics.FileVersionInfo]::GetVersionInfo("\\${pc}\c$\windows\system32\ntoskrnl.exe") |fl

Registry

#REGISTRY - https://blog.netwrix.com/2018/09/11/how-to-get-edit-create-and-delete-registry-keys-with-powershell/
#WARNING - registry is loaded into memory when powershell session starts and I don't know how to update it without starting a new powershell window

#get registry key
Get-Item -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem"

#get registry dword value
Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\' -Name EnableLUA |Select-Object EnableLUA

#search registry
Get-ChildItem -Path hkcu:\ -recurse -ErrorAction SilentlyContinue | Where-Object {$_.Name -like "*Netwrix*"}

#set registry value
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\Power' -Name 'HiberbootEnabled' -value '0'
Set-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem' -Name 'LongPathsEnabled' -Value '1'

#new registry key
New-Item -Path "HKCU:\dummy" -Name NetwrixKey

#new registry parameter
New-ItemProperty -Path "HKCU:\dummy\NetwrixKey" -Name "NetwrixParam" -Value "NetwrixValue"  -PropertyType "String"

#delete registry key
Remove-Item -Path "HKCU:\dummy\NetwrixKey" -Recurse

#delete registry parameter
Remove-ItemProperty -Path "HKCU:\dummy\NetwrixKey" -Name "NetwrixParam"

Services

#show computers with specific service disabled
# $service_name = "winrm" #-StartupType Automatic
$service_name = "remoteregistry"
foreach ($comp in $computers) {
    if (Test-Connection -BufferSize 32 -Count 1 -ComputerName $comp.Name -Quiet) {
        try {
            #Write-Output($comp.Name)
            $svc = Get-Service $service_name -ComputerName $comp.Name
            if ($svc.StartType -eq 'Disabled') {
                Set-Service -Name $service_name -ComputerName $comp.Name -StartupType Manual
                $svc = Get-Service $service_name -ComputerName $comp.Name
                Write-Output("UPDATED - $($comp.Name) $($svc.Name) set StartType to $($svc.StartType) - current status: $($svc.Status)")
            }
        } catch {
            Write-Output("$comp - $($Error[0].Exception)")
        }
    } else {
        Write-Output("DOWN - $($comp.Name)")
    }
}

$ou_path = "dc=corp,dc=example,dc=com"
$computers = @()
$computer_objects = Get-ADComputer -Filter * -SearchBase $ou_path
foreach ($pc in $computers) {
    $computers += $pc.Name
}

$computers = Get-Content pclist.txt

foreach ($comp in $computers) {
    if (Test-Connection -BufferSize 32 -Count 1 -ComputerName $comp -Quiet) {
        try {
            #Write-Output($comp.Name)
            $svc = Get-Service $service_name -ComputerName $comp
            if ($svc.StartType -eq 'Disabled') {
                Set-Service -Name $service_name -ComputerName $comp -StartupType Manual
                $svc = Get-Service $service_name -ComputerName $comp
                Write-Output("UPDATED - $($comp) $($svc.Name) set StartType to $($svc.StartType) - current status: $($svc.Status)")
            }
        } catch {
            Write-Output("$comp - $($Error[0].Exception)")
        }
    } else {
        Write-Output("DOWN - $($comp)")
    }
}

#how to start a remote service (https://devblogs.microsoft.com/scripting/powertip-use-poweshell-to-start-service-on-remote-machine/)
#Get-Service -Name bits  -ComputerName RSLAPTOP01 | Start-service will try starting on local machine; must use | Set-Service -Status Running
$service_name = "winrm"
foreach ($comp in $computers) {
    Write-Output($comp)
    $svc = Get-Service $service_name -ComputerName $comp
    Set-Service -Name $service_name -ComputerName $comp -StartupType Automatic
    Get-Service $service_name -ComputerName $comp | Set-Service -Status Running
    $svc = Get-Service $service_name -ComputerName $comp
    Write-Output("UPDATED - $($comp) $($svc.Name) set StartType to $($svc.StartType) - current status: $($svc.Status)")
}

#how to check service account configured for a service
(Get-WmiObject Win32_Service -ComputerName $env:COMPUTERNAME -Filter "Name='$serviceName'").StartName

#how to find service accounts across multiple computers that aren't LocalSystem or "NT Authority\*"
Invoke-Command -ComputerName $workstations -ScriptBlock {
  $svcs = (Get-WmiObject Win32_Service)
  foreach ($svc in $svcs) {
    if (($svc.StartName -NotContains "LocalSystem") -And ($svc.StartName -NotLike "*NT AUTHORITY\*") -And ($svc.StartName -NotLike "")) {
      $svc_details = $env:COMPUTERNAME + "," + $svc.Name + "," + $svc.Caption + "," + $svc.StartName
      Write-Output $svc_details
    }
  }
}

Shared Folders

#get shared folder list on computer
get-WmiObject -class Win32_Share -computer computername

#list non-admin, non-printer, shared folder list on computer
Get-WmiObject Win32_Share -ComputerName $server | Where-Object {(@('Remote Admin','Default share','Remote IPC') -notcontains $_.Description)}
foreach ($s in $server_list) {
    $val = Get-WmiObject Win32_Share -ComputerName $s | Where-Object {(@('Remote Admin','Default share','Remote IPC','Printer Drivers') -notcontains $_.Description) -and ($_.Path -NotLike "*LocalsplOnly")}
    $shares_hash.Add($s,$val)
}

#search shared folder contents for value
Get-Childitem -Path C:\ -Include *file_name* -Recurse -ErrorAction SilentlyContinue

#get list of folders on a remote share
Get-ChildItem \\server\share -Recurse -Name -Directory

Active Directory

#get os version of computers from active directory
# non-servers #Get-ADComputer -Filter 'operatingsystem -notlike "*server*" -and enabled -eq "true"' `
# domain controllers #Get-ADComputer -Filter 'primarygroupid -eq "516"' `
# servers that are not DCs #Get-ADComputer -Filter 'operatingsystem -like "*server*" -and enabled -eq "true" -and primarygroupid -ne "516"' `
Get-ADComputer -Filter 'enabled -eq "true"' `
-Properties Name,Operatingsystem,OperatingSystemVersion,IPv4Address,lastLogonDate,whenChanged |
Sort-Object -Property OperatingsystemVersion |
Select-Object -Property Name,Operatingsystem,OperatingSystemVersion,IPv4Address,lastLogonDate,whenChanged |ft

#get all computers in an OU
$ou_path = 'ou=admins,dc=corp,dc=example,dc=com'
Get-ADComputer -Filter * -SearchBase $ou_path

#convert arry list of computers to just array of pc names
$pcs = @()
#$pc_list = Get-ADComputer -Filter * -SearchBase $ou_path
$pc_list = Get-ADComputer -Filter 'Name -like "orgws*"'
foreach ($pc in $pc_list) {
    $pcs += $pc.Name
}

#get all users in an OU
$ou_path = 'ou=admins,dc=corp,dc=example,dc=com'
Get-ADUser -Filter * -SearchBase $ou_path

#convert array list of users to just array of usernames
$user_list = Get-ADUser -Filter * -SearchBase $ou_path |Select-Object sAMAccountName
foreach ($user in $user_list) {
    $users += $user.sAMAccountName
}

#function to return full name from AD given the username/sAMAccountName
function get_ad_full_name {
    param (
        $sAMAccountName
    )
    $user = Get-ADUser $sAMAccountName | Select-Object Name 
    return $user.Name
}

#get lastLogonTimeStamp for All Active Users in A.D.
Get-ADUser -Filter {enabled -eq $true} -Properties LastLogonTimeStamp | Select-Object @{Name="Username"; Expression={$_.sAMAccountName}}, Name, @{Name="LastLogonTimeStamp"; Expression={[DateTime]::FromFileTime($_.lastLogonTimestamp).ToString('yyyy-MM-dd_hh:mm:ss')}}

#get lastLogonTimeStamp for all users in A.D.
Get-ADUser -Properties LastLogonTimeStamp | Select-Object @{Name="Username"; Expression={$_.sAMAccountName}}, Name, @{Name="LastLogonTimeStamp"; Expression={[DateTime]::FromFileTime($_.lastLogonTimestamp).ToString('yyyy-MM-dd_hh:mm:ss')}}

#get disabled users in A.D.
Get-ADUser -Filter {enabled -eq $false}

#get list of all computers in active directory
$computers = Get-ADComputer -Filter * -Property *
$computers = $computers |Sort-Object

#powershell copy group membership to new group
Add-ADGroupMember -Identity 'New Group' -Members (Get-ADGroupMember -Identity 'Old Group' -Recursive)

Hyper-V

#create hyper-v VM
New-VM -Name prometheus -NewVHDPath e:\hyper-v\disks\prometheus.vhdx -NewVHDSizeBytes 128GB -MemoryStartupBytes 2GB -SwitchName "Default Switch" -Generation 2

#new VM when VHD already exists
New-VM -Name nessus -VHDPath e:\hyper-v\disks\nessus.vhdx -MemoryStartupBytes 6144MB -SwitchName "Default Switch" -Generation 2

#hyper-v Linux Settings
Add-VMDvdDrive -VMName prometheus -Path e:\hyper-v\disks\ubuntu-20.04.3-live-server-amd64.iso
Set-VMProcessor -VMName prometheus -Count 2
Set-VMFirmware -VMName prometheus -EnableSecureBoot On -SecureBootTemplate "MicrosoftUEFICertificateAuthority"
Set-VMKeyProtector -VMName prometheus -NewLocalKeyProtector
Enable-VMTPM -VMName prometheus
Set-VMSecurity -VMName prometheus -EncryptStateAndVmMigrationTraffic $true

#hyper-v Windows Settings
Add-VMDvdDrive -VMName win2022 -Path e:\hyper-v\disks\win2022-server-20348.169.210806-2348.iso
Set-VMProcessor -VMName win2022 -Count 2
Set-VMFirmware -VMName win2022 -EnableSecureBoot On -SecureBootTemplate "MicrosoftWindows"
Set-VMKeyProtector -VMName win2022 -NewLocalKeyProtector
Enable-VMTPM -VMName win2022
Set-VMSecurity -VMName win2022 -EncryptStateAndVmMigrationTraffic $true

#disconnect ISO image
Get-VMDvdDrive -VMName prometheus | Set-VMDvdDrive -Path $null

Miscellaneous

#send email
Send-MailMessage -SmtpServer mysmtp.com -Port 25 [-Credential $cred] -From user@domain.com -To user@domain.com -Subject test -Body test

#port scan
#from https://techcommunity.microsoft.com/t5/itops-talk-blog/powershell-basics-how-to-scan-open-ports-within-a-network/ba-p/924149
$port = (enter port value)
$network = "enter network value"
$range = 1..254
$ErrorActionPreference= silentlycontinue
$(Foreach ($add in $range)
{ $ip = "{0}.{1}" -F $network,$add
Write-Progress "Scanning Network" $ip -PercentComplete (($add/$range.Count)*100)
If(Test-Connection -BufferSize 32 -Count 1 -quiet -ComputerName $ip){ 
    $socket = new-object System.Net.Sockets.TcpClient($ip, $port)
    If($socket.Connected) { 
        "$ip port $port open"
        $socket.Close() 
    }
    else { "$ip port $port not open " }
}
}) | Out-File $env:userprofile\portscan.csv
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment