建立實際的 PowerShell 模組:搭建函數

您是否在尋找適合您獨特情況的完美 PowerShell 模組而感到困惑?有成千上萬個模組可供選擇,也許您覺得應該就選擇那些已經存在的。嗯,那樣可能會使您的解決方案變得不完整或低效。為什麼不開始創建模組呢?

本指南將指導您創建模組,以構建強大、可重複使用的解決方案,量身定製滿足您的需求。

將您的腳本轉換為可在不同項目中重複使用的強大構建塊!

建立電腦庫存模組

在本指南中,我們將創建一個用於收集計算機硬件信息的 PowerShell 模組。該模組將幫助系統管理員收集並報告跨多個系統的記憶體、存儲和處理器詳細信息。

我們的模組將包括:

  • 用於收集特定硬件信息的功能
  • 使用 PowerShell 會話進行遠程系統支持
  • 統一的輸出格式,以進行一致性報告

這個實際示例演示了在創建系統管理工具時的基本模組開發概念。

設置 PowerShell 模組

在多個系統中管理您的腳本很快可能變得混亂。但是當您的工作流變得困難時,PowerShell 模組就派上用場了。模組是一種結構化的方式,可以將腳本分組並重複使用,以節省時間並減少錯誤。

讓我們結合關鍵概念來構建一個 PowerShell 模組。

首先創建模組目錄並定義模組本身,以組織您的工作。

## Create the module directory in the all-user location
mkdir 'C:\Program Files\PowerShell\Modules\ComputerInventory'

## Create the module to hold the module functions
Set-Content -Path 'C:\Program Files\PowerShell\Modules\ComputerInventory\ComputerInventory.psm1' -Value ''

使用Set-Content命令在所有用户路径中创建名为ComputerInventory的模块。选择此位置是因为它使模块对登录到计算机的任何人都可访问,在企业环境中,多个用户需要访问相同的PowerShell功能至关重要。与特定于用户的位置不同,这个集中式路径确保了系统中模块的一致可用性和更容易的管理。

验证模块的可用性:

## The module is already showing up as available
Get-Module ComputerInventory -ListAvailable

虽然目前只是一个外壳,但这确认它稍后将能够正常加载。

搭建功能架构

良好结构化的模块至关重要,但内部内容才是真正有用的。通过为模块功能创建脚手架,避免浪费时间去弄清楚每个部分的作用,而不是提高生产力。

在类似VS Code的文本编辑器中打开模块,然后搭建功能。

首先创建带有描述性名称的占位符功能。

function Get-MemoryInfo {
    [CmdletBinding()]
    param()

}

function Get-StorageInfo {
    [CmdletBinding()]
    param()

}

function Get-ProcessorInfo {
    [CmdletBinding()]
    param()

}

函数名称遵循一致的动词-名词命名约定。

PowerShell中的函数名称遵循动词-名词的命名约定,这是一种标准化的命名模式。在这种情况下,函数被命名为:

  • Get-MemoryInfo
  • Get-StorageInfo
  • Get-ProcessorInfo

每个函数名称以动词“Get”开头(表示它检索信息),后跟描述所检索信息的名词(Memory、Storage或Processor)。

在 PowerShell 中,這種命名慣例很重要,因為它使函數變得可預測且更容易理解 – 使用者只需查看函數的名稱就能快速掌握函數的用途。

運行以下命令來驗證它們的存在:

Get-Command -Module ComputerInventory

當您運行命令 Get-Command -Module ComputerInventory 時,您將看到類似以下的輸出:

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Function        Get-MemoryInfo                                     1.0.0      ComputerInventory
Function        Get-ProcessorInfo                                  1.0.0      ComputerInventory
Function        Get-StorageInfo                                    1.0.0      ComputerInventory

此命令列出了 ComputerInventory 模組中的所有函數,其中包括我們創建的三個函數:Get-MemoryInfo、Get-StorageInfo 和 Get-ProcessorInfo。

在這個階段,該模組包含函數外殼。讓我們通過定義一致的輸出,來增強這些函數。

使用自定義對象進行標準化輸出

跨腳本的不一致輸出可能將一個簡單的任務轉變為數據解析和故障排除的噩夢。在專業的 PowerShell 開發中,確保一致的輸出是有效腳本撰寫的基石。

使用自定義對象對輸出進行標準化有助於保持函數之間的一致性。

在以下腳本中:

  • 自定義對象包括 ComputerNameHardwareCategoryInfo 屬性。
  • HardwareCategory 屬性將相似的硬體類型分組,ComputerName 設計用於多台計算機的可擴展性。
function Get-MemoryInfo {
    [CmdletBinding()]
    param()

    $outObject = @{
        'ComputerName'      = ''
        'HardwareCategory'  = 'Memory'
        'Info'              = $null
    }

    $outObject
}

function Get-StorageInfo {
    [CmdletBinding()]
    param()

    $outObject = @{
        'ComputerName'      = ''
        'HardwareCategory'  = 'Storage'
        'Info'              = $null
    }

    $outObject
}

function Get-ProcessorInfo {
    [CmdletBinding()]
    param()

    $outObject = @{
        'ComputerName'      = ''
        'HardwareCategory'  = 'Processor'
        'Info'              = $null
    }

    $outObject
}

首先,讓我們重新導入模組以確保我們使用的是最新版本:

Import-Module ComputerInventory -Force

現在,您可以運行這些函數來查看它們的輸出:

PS> Get-MemoryInfo
Name                           Value
----                           -----
Info                           
HardwareCategory              Memory
ComputerName                  

PS> Get-StorageInfo
Name                           Value
----                           -----
Info                           
HardwareCategory              Storage
ComputerName                  

PS> Get-ProcessorInfo
Name                           Value
----                           -----
Info                           
HardwareCategory              Processor
ComputerName

每個函數返回一個具有空的ComputerName和Info屬性的hashtable,但其各自的硬體類別已定義。

為遠端支援添加Session參數

想像需要在數十甚至數百台計算機上運行您的腳本。如果每個函數都需要手動指定計算機名稱,那將變得繁瑣且易出錯。幸運的是,PowerShell Remoting提供了解決方案。

使用Session參數而不是ComputerName參數,以利用PowerShell Remoting:

function Get-MemoryInfo {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [System.Management.Automation.Runspaces.PSSession]$Session
    )

    $outObject = @{
        'ComputerName'      = $Session.ComputerName
        'HardwareCategory'  = 'Memory'
        'Info'              = $null
    }

    $outObject
}

function Get-StorageInfo {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [System.Management.Automation.Runspaces.PSSession]$Session
    )

    $outObject = @{
        'ComputerName'      = $Session.ComputerName
        'HardwareCategory'  = 'Storage'
        'Info'              = $null
    }

    $outObject
}

function Get-ProcessorInfo {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)]
        [System.Management.Automation.Runspaces.PSSession]$Session
    )

    $outObject = @{
        'ComputerName'      = $Session.ComputerName
        'HardwareCategory'  = 'Processor'
        'Info'              = $null
    }

    $outObject
}

該參數確保在擴展至多個系統時具有彈性。

Session參數旨在使用PowerShell Remoting在遠端計算機上執行命令。以下是其強大之處:

  • 它被定義為一個強制性參數,接受PSSession對象(具體為System.Management.Automation.Runspaces.PSSession類型)
  • Session參數通過$Session.ComputerName自動提供計算機名稱,該名稱會在輸出對象中填充

這種方法帶來了幾個優勢:

  • 在處理多個系統時,它可以實現高效的擴展
  • 您可以重複使用相同的會話進行多個操作,而不是為每個函數調用建立新連接,這比為每個函數調用建立單獨連接更有效率
  • 您可以通過創建單個 PSSession 並在所有清單功能中使用它來測試這些功能,就像在示例中展示的那樣,創建一個測試會話:$testSession = New-PSSession -ComputerName SRV2

保存並重新導入模塊:

ipmo ComputerInventory -Force

測試這些功能

如何確保建立後模塊正常運作?測試是確認您模塊的功能是否按預期運行並返回準確數據的重要步驟。跳過此步驟可能會在生產環境中帶來意外驚喜。

建立遠程會話並測試模塊:

$testSession = New-PSSession -ComputerName SRV2

Get-MemoryInfo -Session $testSession
Get-StorageInfo -Session $testSession
Get-ProcessorInfo -Session $testSession

每個功能應返回一個帶有預期屬性和正確計算機名稱的對象。這些功能構成了強大清單工具的基礎。

根據所示的代碼,當您使用遠程會話測試這些功能時,輸出將類似於:

PS> $testSession = New-PSSession -ComputerName SRV2
PS> Get-MemoryInfo -Session $testSession
Name                           Value
----                           -----
Info                           
HardwareCategory              Memory
ComputerName                  SRV2

PS> Get-StorageInfo -Session $testSession
Name                           Value
----                           -----
Info                           
HardwareCategory              Storage
ComputerName                  SRV2

PS> Get-ProcessorInfo -Session $testSession
Name                           Value
----                           -----
Info                           
HardwareCategory              Processor
ComputerName                  SRV2

每個功能返回一個哈希表,其中包含計算機名稱(來自會話)、具體硬件類別和一個信息字段(目前為空,但旨在容納實際硬件信息)。

結論

在本文中,您了解了為應對沒有通用模塊能夠解決的獨特挑戰而創建自己的 PowerShell 模塊是至關重要的原因。我們探討了自定義模塊如何對您環境中的專業配置或流程產生重大影響。

這只是我們與ComputerInventory模組的旅程開始。在即將到來的部落格文章中,我們將通過添加真實硬件信息收集功能、錯誤處理和高級遠程管理功能來擴展這個基礎。

敬請期待,讓我們將這個基本框架轉變成系統管理員的強大工具!

Source:
https://adamtheautomator.com/powershell-module-functions/