动态

详情 返回 返回

簡單的Powershell腳本(二) - 动态 详情

目錄
  • 簡單瞭解Powershell腳本
    • 在 PowerShell 中發現命令
      • 使用 Get-Member 發現對象
      • 按類型搜索
      • 使用 Select-Object 篩選 Get-Member 結果
    • 選擇數據
      • 獲取完整響應
      • 排序
      • 使用格式設置和篩選
    • 編寫你的第一個 PowerShell 代碼
      • Hello World!
      • Powershell 中的編譯代碼
      • 基礎語法認識
        • 須知
        • 查看配置文件
        • 聲明參數
        • if elseif else
        • 錯誤處理
  • PowerShell變量、數組和哈希表
    • 變量
      • 創建變量
      • 變量類型
      • 變量的方法和屬性
      • 字符串變量和方法
      • 日期變量和方法
        • DateTime 屬性
        • DateTime 方法
    • 數組和哈希表
      • 定義數組
      • 數組的屬性和方法獲取
      • 使用數組列表
      • 定義哈希表
      • 使用哈希表

簡單瞭解Powershell腳本

在 PowerShell 中發現命令

使用 Get-Member 發現對象

  • Get-Member的作用:
    探查任何 PowerShell 命令輸出對象的屬性(Property) 和方法(Method)

  • 查看所有方法
    這裏會輸出Get-Process 所有進程的方法

Get-Process | Get-Member -MemberType Method
  • -Name: 按名稱查找特定成員(支持通配符)
    這裏會輸出你 Get-Process 所有進程的有關於"*Handle*"這個通配符匹配的方法和屬性
Get-Process | Get-Member -Name "*Handle*"
  • 如果你要查看指定的進程、服務等等,你可以先進行篩選再給到Get-Member獲取他的內容
    • 其實和不指定進程的時候沒有區別:兩種操作方式,Get-Member 顯示的都是 System.Diagnostics.Process 類型的方法列表,與具體是哪個進程實例、有多少個實例無關。
    • Get-Member 的用途:探索對象類型的結構和能力(有哪些屬性和方法)。
# 獲取ctfmon進程的所有方法
Get-Process -Name ctfmon | Get-Member -MemberType Method
等同於
Get-Process | Get-Member -MemberType Method

實際使用

  • 屬性查看
# 先通過Get-Member 獲取某個東西的屬性(不一定是進程),看你要查看哪個屬性
Get-Process -Name 'ctfmon' | Get-Member -MemberType Properties

# 比如我查看了所有屬性,想要查看Path屬性,用法如下:
(Get-Process -Name 'ctfmon').Path
  • 方法使用
# 先通過Get-Member 獲取某個東西的方法有哪些(不一定是進程),看你要使用哪個方法
# 其實可以不指定進程名字,因為我們對進程的操作方法一般都是一樣的!!!上面也有對此進行解釋
# 不過我還是覺得-Name 指定一下好點,養成好習慣,儘可能減少失誤的可能性
Get-Process | Get-Member -MemberType Method 

按類型搜索

假設你調用了 PowerShell 命令來列出特定進程的所有成員。 結果的前幾行看起來類似於以下輸出:

TypeName: System.Diagnostics.Process

Name                       MemberType     Definition
----                       ----------     ----------
Handles                    AliasProperty  Handles = Handlecount

第一行指示類型為 System.Diagnostics.Process。 使用此類型作為搜索參數,查找使用此類型的其他 cmdlet。 下面是一個示例命令:

Get-Command -ParameterType Process

# 當然也可以直接輸入全稱
Get-Command -ParameterType System.Diagnostics.Process

使用 Select-Object 篩選 Get-Member 結果

Select-Object 就是篩選特定列,決定要顯示的列。
沒啥好説的,不僅僅是搭配Get-Member,很多都可以,這裏只是一個小例子
請記住,返回的答案已是響應中所有列的子集。
需要一個逗號分隔的列名稱列表,可以使用通配符對列名進行匹配

Get-Process -Name 'ctfmon' | Get-Member | Select-Object Name, MemberType

選擇數據

獲取完整響應

有兩種方法:

Get-Process ctfmon | Format-List -Property *

Get-Process ctfmon | Select-Object *

排序

在管道中使用 Sort-Object 時,PowerShell 先使用默認屬性對輸出數據排序。
如果不存在此類屬性,它會嘗試比較對象本身。

  • 可以選擇按特定列排序
    降序對列 Name 進行排序
Get-Process | Sort-Object -Descending -Property Name
  • 自定義表達式按列 Name 和 CPU 進行排序,並控制每列的排序順序
    首先按進程名稱的字母逆序(Z-A)排列所有名為 'some process' 的進程,對於名稱相同的進程,再按 CPU 使用量的升序(低到高)進行排列。
Get-Process 'some process' | Sort-Object -Property @{Expression = "Name"; Descending = $True}, @{Expression = "CPU"; Descending = $False}

使用格式設置和篩選

正確設置格式,將格式設置作為最後一項操作
比如下面這個就輸出空值,因為已經格式化了,不是對象了,所以select-objetc後選不到對象即為空值:

Get-Process 'ctfmon' | Format-Table Name,CPU | Select-Object Name, CPU

關鍵在於 Format-TableFormat-List 等格式化命令的輸出不再是原始的進程對象,而是專門用於格式化顯示的格式化指令對象


再次強調一遍:正確設置格式,將格式設置作為最後一項操作


編寫你的第一個 PowerShell 代碼

若運行不了腳本,請嘗試:

  • 管理員運行powershell
  • 如果執行不了可以設置一下策略(臨時):Set-ExecutionPolicy
    • 然後輸入:RemoteSigned

解釋:

  • Set-ExecutionPolicy:如果使用的是 Windows 計算機,則可以使用此 cmdlet 更改執行策略的值。 它採用 -ExecutionPolicy 參數。
    • Restricted 表示無法運行腳本
    • RemoteSigned 表示可以運行在本地計算機上編寫的腳本

Hello World!

  • Read-Host:接收用户輸入
    • -Prompt 提示信息
  • $name 為變量,用於接收用户輸入的內容
$name = Read-Host -Prompt "Please enter your name"

需要注意的是:Read-Host是會return用户輸入的值的,所以説如果你不用變量接收的情況下,比如你直接在終端輸入Read-Host -Prompt "Please enter your name",用户輸入完成後,會直接輸出在終端。


  • Write-Output
    相當於cmd的echo
    你可以通過Get-Alias -Definition Write-Output來查看是不是,同時還會發現另一個別名:write
  • 直接將$name放在字符串裏面,因為我們上面已經通過用户的輸入給$name變量一個值了
Write-Output "Congratulations $name! You have written your first code with PowerShell!"

輸出如下:

練習:
獲取時間 && 用户輸入

# Today's date is <current date>.
# Today is the day <your name> began a PowerShell programming journey.
$date = Get-Date
$name = Read-Host -Prompt "Plz enter your name"
Write-Output "Today's date is $date."
Write-Output "Today is the day $name began a PowerShell programming journey."

Powershell 中的編譯代碼

PowerShell 被編譯成抽象語法樹 (AST),首先在內存中,然後運行。 但要使用 PowerShell,你不需要在這裏進行深入研究。 你所需要知道的是,計算機在查找主要問題時首先檢查 AST 中的代碼。 然後,如果一切正常,則計算機會運行程序,而不需要編譯的可執行程序。 此方法非常有用,因為它可確保代碼在計算機運行代碼之前正確運行。 否則,可能會由於語法錯誤而進行更改並停止。 相比之下,Python 等解釋型語言會一直運行代碼,直到發現語法中有錯誤。

基礎語法認識

學習目標

  • 編寫並運行腳本。
  • 使用變量和參數增加腳本的靈活性
  • 應用流控制邏輯做出明智的決策
  • 通過添加錯誤管理增加腳本的可靠性

須知

  • powershell中轉義符號是反引號:( ` )
  • 變量用$ 符號
  • $( 表達式 ) :雙引號內使用這個可以對變量進行表達式操作
    "表達式:$($PI + 1)" 那這個就是表示在該字符串中先對變量$PI進行了加一操作後再輸出整個字符串。

查看配置文件

查看所有不同作用範圍的配置文件

$Profile | Select-Object *

選擇你要編輯的配置文件,將自定義項添加到文本文件並保存。 下一次啓動會話時,將應用所做的更改。

  • 嘗試修改當前配置文件:
New-Item -ItemType "file" -Value 'Write-Host "Hello xxx, Welcome back" -foregroundcolor Green' -Path $Profile.CurrentUserCurrentHost -Force

聲明參數

# CreateFile.ps1
Param (
  $Path
)
New-Item $Path # Creates a new file at $Path.
Write-Host "File $Path was created"
  • 使用的時候就有用:
    ./CreateFile.ps1 -Path './newfile.txt'

解釋:

很明顯了,上面就是通過使用Param() 來定義參數,變量名就是參數名,使用的時候用 - 符號 加上變量名即可傳入值到變量中為後續腳本代碼的使用。

作為一名專業的技術人員,我們不能僅僅只考慮腳本在理想情況下生效,還需要考慮各種情況。
定義參數時,需要考慮以下事項:

  • 是否必需? 參數是可選的還是必需的?
  • 允許哪些值? 哪些值合理?
  • 它是否接受多種類型的值? 參數是否接受任何類型的值,如字符串、布爾值、整數和對象?
  • 參數能否依賴於默認值? 是否可以完全省略值並改為依賴於默認值?
  • 可以進一步改進用户體驗嗎? 是否可以通過提供幫助消息為用户提供更清楚的提示?

使用 If/Else。 使用 If/Else 構造,可以檢查參數的值,然後確定要執行的操作。 下面是一個示例:
如果沒有為 Write-Error 提供值,則腳本將運行 $Path

Param(
   $Path
)
If (-Not $Path -eq '') {
   New-Item $Path
   Write-Host "File created at path $Path"
} Else {
   Write-Error "Path cannot be empty"
}

使用 Parameter[] 修飾器
更好的方法是使用 Parameter[] 修飾器
它可以自己完成簡單的檢測,不用我們自己去判斷是否空值:
如果運行此腳本並省略 $Path 的值,則會出現一個提示該值缺失的對話框:

Param(
   [Parameter(Mandatory)]
   $Path
)
New-Item $Path
Write-Host "File created at path $Path"

如果運行此腳本並省略 $Path 的值,則會出現一個提示該值缺失的對話框:

cmdlet CreateFile.ps1 at command pipeline position 1
Supply values for the following parameters:
Path:

可通過為用户提供幫助消息來改進此修飾器,用户在運行腳本時將看到該消息:

[Parameter(Mandatory, HelpMessage = "Please provide a valid path")]

運行腳本時,你會收到一條消息,提示需要鍵入 !? 獲取詳細信息:

cmdlet CreateFile.ps1 at command pipeline position 1
Supply values for the following parameters:
(Type !? for Help.)
Path: !?  # You type !?
Please provide a valid path  # Your Help message.

分配類型。 例如,如果為參數分配類型,你可以指定該參數只接受字符串,而不接受布爾值。 這樣,用户就知道了期望結果。 可以在參數前面加上類型(用括號括住),為該參數分配類型:

Param(
   [string]$Path
)

練習

嘗試寫一個備份當前目錄文件的腳本

# backup test file

$date = Get-Date -Format "yyyy_MM_dd"
Compress-Archive -Path "./" -CompressionLevel Fastest -DestinationPath "backup_$date.zip"
Write-Output "Success Backup to ./backup_$date.zip"

該腳本調用 Compress-Archive 並使用以下這三個參數:

  • -Path,這是要壓縮的文件的目錄。
  • -CompressionLevel,用於指定文件的壓縮量。
  • -DestinationPath,這是所生成的壓縮文件的名字。

嘗試將參數添加到腳本,而不是固定的路徑

# backup test file

Param(
	[Parameter(Mandatory, HelpMessage = 'Please check the path and destination path')]
    [String]$Path = './',
    [String]$Destination = './'
)

$date = Get-Date -Format "yyyy_MM_dd_HH_mm_ss"
Compress-Archive -Path "$Path" -CompressionLevel Fastest -DestinationPath "$($Destination + 'backup_' + $date + '.zip')"
Write-Output "$('Success Backup to' + $Destination + 'backup_' + $date + '.zip')"

if elseif else

運算符

  • PowerShell 提供了兩個內置參數,用於確定表達式是 True 還是 False
    • $True 指示表達式為 True
    • $False 指示表達式為 False
  • le:小於
  • gt:大於
  • eq:等於
  • -Not:否,取反

If

If(表達式){
	xxx
}

Else

If(表達式1){
	xxx
}Else{
	xxx
}

ElseIf

If(表達式1){
	xxx
}ElseIf(表達式2){
	xxx
}ElseIf(表達式3){
	xxx
}Else{
	xxx
}

練習:

按照上面我的寫的一個備份腳本,這個缺點是當我們就算路徑不存在還是會去嘗試執行所有代碼,那我們就可以利用上if else等等來進行一個流處理。

# backup test file

Param(
    [String]$Path = './',
    [String]$Destination = './'
)
if(-Not(Test-Path $Path)){ # if dir not exist
    Throw "The source directory $Path does not exist, please specify an existing directory"
}
If (-Not (Test-Path $Destination)){
    Throw "The source directory $Path does not exist, please specify an existing directory"
}Else{
    $date = Get-Date -Format "yyyy_MM_dd_HH_mm_ss"
    Compress-Archive -Path "$Path" -CompressionLevel Fastest -DestinationPath "$($Destination + 'backup_' + $date + '.zip')"
    Write-Output "$('Success Backup to' + $Destination + 'backup_' + $date + '.zip')"
}

這裏涉及到了錯誤處理,後面接着講

錯誤處理

使用 Try/Catch/Finally 管理錯誤

有三個相關構造可幫助管理此類錯誤:

  • Try。 將使用 Try 塊封裝一個或多個語句。 將要運行的代碼(例如,寫入到數據源的代碼)放在大括號內。 Try 必須至少有一個 Catch 或 Finally 塊。 其如下所示:
Try {
   # Statement. For example, call a command.
   # Another statement. For example, assign a variable.
}
  • Catch。 發生錯誤時,將使用此關鍵字捕獲或管理錯誤。 然後將檢查異常對象,以瞭解發生的錯誤的類型、發生的位置以及腳本是否可以恢復。 Catch 緊跟在 Try 之後。 如果需要,可以包括多個 Catch,每種類型的錯誤一個。 下面是一個示例:
Try {
   # Do something with a file.
} Catch [System.IO.IOException] {
   Write-Host "Something went wrong"
}  Catch {
   # Catch all. It's not an IOException but something else.
}

此腳本嘗試運行執行一些 I/O 工作的命令。 第一個 Catch 捕獲特定類型的錯誤:[System.IO.IOException]。 最後的 Catch 捕獲任何非 [System.IO.IOException] 的內容。

  • Finally。 不管是否出現錯誤,此塊中的語句都將運行。 可能不會常使用此塊,但它對清理資源很有用。 若要使用它,請將其添加為最後一個塊:
Try {
   # Do something with a file.
} Catch [System.IO.IOException] {
   Write-Host "Something went wrong"
}  Catch {
   # Catch all. It's not an IOException but something else.
} Finally {
   # Clean up resources.
}

錯誤信息解析:
我們在捕獲錯誤的上下文中已經討論過異常對象。 你可以使用這些對象來檢查問題所在,並採取相應的措施。 異常對象包含:

  • A message:消息會簡單説明問題所在。
  • The stacktrace:Stacktrace 將指出在發生錯誤之前運行了哪些語句。 假設你先後調用了函數 A、B、C。腳本在 C 處停止響應。Stacktrace 將顯示此調用鏈。
  • The offending row:異常對象還會顯示錯誤發生時腳本正在運行的行。 此信息有助於調試代碼。

那麼,如何檢查異常對象呢? 有一個內置的變量 $_,該變量具有 exception 屬性。 例如,可使用 $_.exception.message 獲取錯誤消息。 在代碼中,它可能如下所示:

Try {
     # Do something with a file.
   } Catch [System.IO.IOException] {
     Write-Host "Something IO went wrong: $($_.exception.message)"
   }  Catch {
     Write-Host "Something else went wrong: $($_.exception.message)"
   }

自定義處理動作

  • Continue
  • Ignore:比 SilentlyContinue 更徹底。既不顯示錯誤,也將其記錄到 $Error 變量中。就像錯誤從未發生過一樣。
  • Inquire:詢問,當錯誤發生時,暫停執行並向用户詢問下一步操作(Y-繼續, A-全部繼續, H-掛起, ?-幫助)。
  • SilentlyContinue:靜默繼續,不在屏幕上顯示錯誤信息,但錯誤仍然會被記錄到自動變量 $Error 中。命令繼續執行。
  • Stop:停止
  • Suspend:掛起,此參數僅適用於 PowerShell 工作流 (Workflow)。當錯誤發生時,工作流會暫停並允許用户調查,然後可以選擇恢復或終止。
Try {
   Get-Content './file.txt' -ErrorAction Stop
} Catch {
   Write-Error "File can't be found"
}

Throw 拋出

  • 如果異常未被任何 Catch 塊捕獲,最終會顯示在控制枱上。
  • 在 Catch 塊中:通過 $_ 或 $PSItem 變量訪問。
Catch {
    $ErrorMessage = $_.Exception.Message   # 獲取錯誤信息
    $ErrorType = $_.Exception.GetType().FullName # 獲取錯誤類型
}
  • 自動變量 $Error:PowerShell 會自動將所有錯誤記錄到全局的 $Error 數組中,最新的錯誤在索引 [0]。即使異常被 Catch 處理了,也依然會記錄到 $Error 中。你可以使用 $Error[0] | FL * 查看一個錯誤的全部詳細信息。

案例:
下面這個就是Throw拋出後,因為有catch,且catch將錯誤信息打印出來了,所以根據catch的錯誤信息拼接起來打印。
(否則一般情況下,你直接Throw的話,他就是直接打印錯誤信息在終端上)

Try {
   If ($Path -eq './forbidden') 
   {
     Throw "Path not allowed"
   }
   # Carry on.

} Catch {
   Write-Error "$($_.exception.message)" # Path not allowed.
}

PowerShell變量、數組和哈希表

變量

通過查看名為“變量”的 PowerShell 驅動器的內容來查看內存中包含的變量,請使用以下命令:

Get-ChildItem Variable:
或者直接使用↓↓,二者一樣
Get-Variable

下面顯示的變量,有的是你自己在當前session中定義的,有的是系統的。

你所看到的都可以通過添加一個$符號來打印出來他的值,當你反正你直接打印所有的時候已經是能看到他的值value了

創建變量

簡單的創建就是直接$變量名

但是遇到有空格的那就需要添加大括號 { }
${log file}

變量名稱不區分大小寫, 變量 $USER 和 $user 是可以互換的。
為了提高可讀性,常見的約定是使用小寫字符,並將變量名稱中每個單詞的第一個字母大寫。
例如,$logFile 和 $LogFile 都是常用的。

但是當變量用於腳本中的參數時,第一個單詞應大寫,以便與 cmdlet 使用的參數保持一致。
↑↑這個很關鍵

Param{
	這裏的參數就是建議使用大寫第一個字母,因為這個參數變量在實際使用的時候可以tab出來,tab出來的大小寫和你這裏寫的大小寫一樣,所以建議是使用第一個字母大小寫,儘量和其他的cmdlet一致
}

還有一種方法創建變量:
使用此 cmdlet 時,在引用名稱時不包括 $ 符號,如以下示例所示

Set-Variable -Name num1 -Value 5

變量類型

如果未分配變量類型,Windows PowerShell 會根據賦給變量的值自動分配類型。

類型 描述
String 字符串變量存儲可以包含特殊字符的文本。 例如“This is a string.”
Int 32 位整型變量存儲不帶小數位的數字。 例如 228。
Double 64 位浮點變量存儲可包含小數位的數字。 例如 128.45。
DateTime DateTime 變量存儲包含日期和時間的日期對象。 例如 2022 年 1 月 5 日上午 10:00。
Bool 布爾變量只能存儲值 $true 或 $false

若想要知道某個變量的類型,可以通過將 GetType() 方法追加到變量名後來查看變量的類型。 例如:

$date.GetType()

變量的方法和屬性

1.我們可以利用tab方式來查看,方法是輸入變量名並在後面加上一個點,選擇“Tab”鍵時,將顯示可用於變量的屬性和方法,這樣會一個個給你提示出來,你自己慢慢查看即可

2.顯示特定變量的所有可用屬性和方法

$num1 | Get-Member

字符串變量和方法

字符串變量常用於腳本中。 可以使用字符串來存儲用户輸入和其他文本數據。 有許多可用於操作字符串的方法。 其中有多種方法很少使用,但最好了解它們以備不時之需。

字符串變量只有一個屬性,即“Length”。 查看字符串變量的長度時,它會返回字符串中的字符數。 例如:

$logFile.Length

下表列出了一些可用於字符串變量的方法。

方法 説明
Contains(string value) 確定變量是否包含特定字符串。 結果為 $true 或 $false
Insert(int startindex,string value) 在指定的字符下標處插入文本字符串。
Remove(int startindex,int count) 從字符串中刪除指定數量的字符(從指定的字符下標開始)。 如果未指定計數,字符串會在指定的字符下標處被截斷。
Replace(string value,string value) 用第二個字符串替換第一個字符串的所有實例。
Split(char separator) 在字符指定的點處將單個字符串拆分為多個字符串。
ToLower() 將字符串轉換為小寫。
ToUpper() 將字符串轉換為大寫。

日期變量和方法

創建的許多腳本都需要引用當前日期或之前的時間點。 例如,若要確保唯一性,可能需要根據當前日期創建日誌文件名。 此外,可能會在 AD DS 中搜索很長時間都未登錄的用户。 可以使用 DateTime 變量來完成這些任務。

DateTime 屬性

DateTime 變量包含日期和時間。
可以使用 DateTime 變量屬性訪問日期或時間的特定部分。 下表列出了 DateTime 變量的一些可用屬性。

properties 説明
Hour 以 24 小時格式返回具體小時。
Minute 返回具體分鐘。
Second 返回具體秒數。
TimeOfDay 返回一天具體時間的詳細信息,包括小時、分鐘和秒。
Date 僅返回日期,不返回時間。
DayOfWeek 返回星期幾,例如:星期一。
Month 以數字的形式返回月份。
Year 返回年份。

DateTime 方法

DateTime 變量還提供了許多可用於操作時間的方法。
這些方法提供了添加或減去時間的方法,還有一些方法可用於以特定方式操作 DateTime 變量的輸出。
下表列出了一些 DateTime 變量方法。

方法 説明
AddDays(雙精度值) 添加指定天數。
AddHours(雙精度值) 添加指定小時數。
AddMinutes(雙精度值) 添加指定分鐘數。
AddMonths(整數月份) 添加指定月數。
AddYears(整數值) 添加指定年份。
ToLongDateString() 以字符串形式返回長格式的日期。
ToShortDateString() 以字符串形式返回短格式的日期。
ToLongTimeString() 以字符串形式返回長格式的時間。
ToShortTimeString() 以字符串形式返回短格式的時間。

數組和哈希表

定義數組


數組元素允許類型不一樣


通過在逗號分隔的列表中提供多個值來創建數組
例如:

$computers = "LON-DC1","LON-SRV1","LON-SRV2"
$numbers = 228,43,102

還可以使用命令的輸出創建數組
例如:

$users = Get-ADUser -Filter *
$files = Get-ChildItem C: 

GetType() 方法來驗證變量是否為數組,列出的 BaseType 將為 System.Array

$arr=1,2,3,4
$arr.GetType()

可以在準備好將內容放入空數組之前創建空數組。 稍後在腳本中有一個向數組添加項的循環時,這會很有用
例如:

$newUsers = @()

還可以在向變量添加單個值時強制創建數組。 這將創建一個具有單個值的數組,便於以後向其中添加項
例如:

[array]$computers="LON-DC1"

數組的屬性和方法獲取

這裏是為了告訴你,數組和數組元素的屬性和方法獲取是不同的

  • 獲取數組中每個項的屬性和方法
$arr | Get-Member
  • 獲取數組的屬性和方法(這裏不是獲取數組元素的東西哈)
Get-Member -InputObject $arr

使用數組列表

每個項目分配一個從 0 開始的索引號
若要顯示特定項,請將索引號放在變量名稱後面的括號中
以下示例顯示數組中存儲在變量 $users 中的第一項:

$arr[0]

可以向數組添加新項,新項可以是單個元素也可以是列表,當然也可以是不同類型的數組:

$arr = $arr + $arrtest

# 在powershell中也有這種寫法
$arr += $arrtest

上述都是説數組而已,他們的類型是 System.Array,不是數組列表ArrayList

Windows PowerShell 創建的默認數組類型是固定大小的數組。 這意味着,將項添加到數組時,該數組實際上是使用附加項重新創建的。 使用相對較小的數組時,這不是問題。 但是,如果逐個向數組添加數千個項目,則每次重新創建數組都會對性能產生負面影響。 使用固定大小的數組的另一個問題是刪除項。 沒有簡單的方法可從固定大小的數組中刪除項。

若要在賦值時創建數組列表,請使用以下語法:

[System.Collections.ArrayList]$computers = "LON-DC1","LON-SVR1","LON-CL1"

若要創建空且已準備好添加項的數組列表,請使用以下語法:

$computers=New-Object System.Collections.ArrayList

使用數組列表時,可以使用方法來添加和刪除項:

$computers.Add("LON-SRV2")
$computers.Remove("LON-CL1")

如果要根據索引號從數組列表中刪除項,請使用 RemoveAt() 方法。 例如:

$computers.RemoveAt(1)

定義哈希表

哈希表表示與數組類似的概念,因為它存儲多個項,但不同於數組使用索引號來確定每項,哈希表使用唯一鍵來實現這一點。
鍵是一個字符串,它是項的唯一標識符。 哈希表中的每個鍵都與值相關聯。

使用哈希表來存儲 IP 地址和計算機名,如下表所示:

Key Value
LON-DC1 192.168.0.10
LON-SRV1 192.168.0.11
LON-SRV2 192.168.0.12

如果哈希表名為 $servers,可以使用以下任意選項訪問哈希表中的第一項:

$servers.'LON-DC1'
$servers['LON-DC1']

因為我們的這個Key有特殊符號 -,所以需要引號包起來,若你的變量就是正常的沒有啥特殊字符就可以直接使用而不用引號包裹。

使用哈希表

以下命令創建一個名為 $servers 的哈希表來存儲服務器名稱和 IP 地址:

# 下面是放在單獨的行,所以使用分號隔開
$servers = @{"LON-DC1" = "172.16.0.10"; "LON-SRV1" = "172.16.0.11"}

# 下面是每一項都單獨一行,所以不用分號隔開
$servers = @{
"LON-DC1" = "172.16.0.10"
"LON-SRV1" = "172.16.0.11"
}

請注意上面的示例中的以下語法:

  • 它以 @ 符號開頭。
  • 鍵和關聯的值括在大括號中。
  • 項之間用分號分隔。

更新鍵的值是直接賦值即可

$servers."LON-SRV2"="172.16.0.100"

查看哈希表可用的所有屬性和方法

$servers | Get-Member
user avatar yangtb 头像
点赞 1 用户, 点赞了这篇动态!
点赞

Add a new 评论

Some HTML is okay.