PowerShell再利用可能セッション:持続的なリモート接続ガイド

リモートシステムの管理は、複数のマシンでコマンドを実行する際にすぐに頭痛の種になることがあります。システムへの再接続のための常に行き来する作業は、時間を無駄にし、作業フローを遅くさせる可能性があります。聞き覚えがありますか?心配しないでください、もっと良い方法があります!

このガイドでは、リモートシステムの管理をより速く、簡単に、効率的にするために再利用可能なPowerShellリモートセッションを使用する方法を学びます。

PowerShellリモートスキルをレベルアップする準備はできましたか?さあ、始めましょう!

セッションの作成と使用

リモートシステムで作業する際、コマンドを実行するたびに再接続することが最も面倒な作業の一つになることがあります。そのような場合、再利用可能なセッションが登場します。

持続的なセッションを作成することで、継続的な接続を維持できます。これにより、複数のコマンドを繰り返し実行する際に接続と切断を行う必要がなくなります。

まず、再利用可能なセッションを作成する必要があります。

New-PSSessionコマンドレットは、リモートコンピュータへの持続的な接続を確立します:

$session = New-PSSession -ComputerName SRV2

このセッションオブジェクトは、Invoke-Commandのようなコマンドに渡すことができ、スクリプト全体で同じセッションを再利用することができます。

例えば、基本的なコマンドを実行して接続をテストすることができます:

Invoke-Command -Session $session -ScriptBlock { hostname }

再利用可能なセッションは、リモートシステム上で変数を保存し、取得することも可能です:

Invoke-Command -Session $session -ScriptBlock { $foo = 'Please be here next time' }
Invoke-Command -Session $session -ScriptBlock { $foo }

この持続的なストレージ機能は、再利用可能なセッションの大きな利点であり、複数のコマンドにわたって状態を維持することを可能にします。

リモート使用のための関数の適応

インベントリ機能を再利用可能なセッションで動作するように適応しましょう。

まず、セッションオブジェクトを受け入れるためにSessionパラメータを追加します。このとき、Get-Memberコマンドレットを使用してセッションオブジェクトのタイプを特定します。

$session | Get-Member

セッションオブジェクトがSystem.Management.Automation.Runspaces.PSSessionタイプであることが特定されたら、次のステップはGet-WmiObjectValue関数を定義することです。

この関数はセッションパラメータを使用してリモート実行を可能にし、リモートシステムでスクリプトブロックを実行し特定のWMIプロパティを取得できるようにします。

function Get-WmiObjectValue {
    [CmdletBinding()]
    param(
        # Specify the name of the WMI property to query
        [Parameter(Mandatory)]
        [string]$PropertyName,

        # Specify the name of the WMI class to query
        [Parameter(Mandatory)]
        [string]$WmiClassName,

        # Specify the remote session object to use for invoking the command
        [Parameter(Mandatory)]
        [System.Management.Automation.Runspaces.PSSession]$Session
    )

    # Define the script block to execute on the remote machine
    $scriptBlock = {
        # Get the sum of the specified property from the WMI class
        $number = (Get-CimInstance -ClassName $using:WmiClassName | Measure-Object -Property $using:PropertyName -Sum).Sum

        # Convert the sum to gigabytes
        $numberGb = $number / 1GB

        # Round the result to 2 decimal places
        [math]::Round($numberGb, 2)
    }

    # Execute the script block on the remote machine using the provided session
    Invoke-Command -Session $Session -Scriptblock $scriptBlock
}

この関数を試してみて、何が起こるか見てみましょう。

Get-WmiObjectValue -PropertyName Capacity -WmiClassName Win32_PhysicalMemory -Session $session

いつかこのエラーに遭遇するかもしれませんが、心配いりません。続けて読んで、このエラーをどのように対処すればよいかを学びます。

認証の問題に対処する

「アクセスが拒否されました」エラーが発生した場合、十分な権限がない可能性があります。再利用可能なセッションは、作成に使用された資格情報を継承します。

システムで現在認証されているユーザーのユーザー名を確認してください:

whoami

リモートコンピューターでWMIをクエリする権限がないドメインユーザーである場合は、セッションを作成する際に代替資格情報を指定するためにInvoke-Commandを昇格させます。

まず、セッション作成時に代替資格情報を指定するためにGet-Credentialコマンドレットで資格情報オブジェクトを作成します。

$adminCred = Get-Credential -UserName adam

認証されたら、セッションをテストします:

Invoke-Command -Session $session -Scriptblock {hostname} -Credential $adminCred

このテストは、インベントリ機能を実行する前にセッションが期待どおりに動作することを確認します。

しかし、セッションが機能しない場合、すでに誤った資格情報で作成されていた可能性があります。その場合は、現在のセッションを削除する必要があります。

Remove-PSSession -Session $session

Remove-PSSession コマンドレットは、ローカルコンピュータとリモートコンピュータの両方でセッションを削除します。

古いセッションを削除したら、別の新しいセッションを作成します。ただし、今回は管理者ユーザーとして認証されたセッションを作成します。

$session = New-PSSession -ComputerName SRV2 -Credential $adminCred

新しいセッションが機能することを確信したら、関数をもう一度試してみましょう。

Invoke-Command -Session $session -Scriptblock {hostname} -Credential $adminCred

新しいセッションが機能することを確信したら、関数をもう一度試してみましょう。

Get-WmiObjectValue -PropertyName Capacity -WmiClassName Win32_PhysicalMemory -Session $session

すべてを一緒にまとめる

大変な作業は終わり、すべてを1つのスクリプトにまとめる時が来ました。

この最終スクリプトは、インベントリ情報を収集し、結果を表示し、セッションをクリーンアップします。

function Get-WmiObjectValue {
    [CmdletBinding()]
    param(
        # Specify the name of the WMI property to query
        [Parameter(Mandatory)]
        [string]$PropertyName,

        # Specify the name of the WMI class to query
        [Parameter(Mandatory)]
        [string]$WmiClassName,

        # Specify the remote session object to use for invoking the command
        [Parameter(Mandatory)]
        [System.Management.Automation.Runspaces.PSSession]$Session
    )

    # Define the script block to execute on the remote machine
    $scriptBlock = {
        # Get the sum of the specified property from the WMI class
        $number = (Get-CimInstance -ClassName $using:WmiClassName | Measure-Object -Property $using:PropertyName -Sum).Sum

        # Convert the sum to gigabytes
        $numberGb = $number / 1GB

        # Round the result to 2 decimal places
        [math]::Round($numberGb, 2)
    }

    # Execute the script block on the remote machine using the provided session
    Invoke-Command -Session $Session -Scriptblock $scriptBlock
}

## Grab the alternate credential: Get-CimInstance will work on the remote computer
$adminCred = Get-Credential -UserName adam

## Create a session authenticating as the adam (admin) user
$session = New-PSSession -ComputerName SRV2 -Credential $adminCred

## Find the total memory and total volume storage space on the remote computer
$totalMemoryGb = Get-WmiObjectValue -PropertyName Capacity -WmiClassName Win32_PhysicalMemory -Session $session
$totalStorageGb = Get-WmiObjectValue -PropertyName FreeSpace -WmiClassName Win32_LogicalDisk -Session $session

Write-Host "The computer $($session.ComputerName) has $totalMemoryGb GB of memory and $totalStorageGb GB of free space across all volumes."

## Remove the shared session
Remove-PSSession -Session $session

スクリプトを保存して実行Get-InventoryInfo.ps1)して、意図したとおりに機能するか確認してください。

結論

このチュートリアルでは、再利用可能なセッションを使用してリモートコンピュータを効果的に管理する堅牢な関数を構築する方法を学びました。複数のコマンド間で持続的な接続を維持し、各タスクを切断することなくリモートシステムで複雑なタスクを実行する方法を学びました。

これからは、この知識を活用して、再利用可能なセッションを大規模な自動化ワークフローに組み込むことができます。例として、インベントリ機能を拡張して追加のシステムメトリクスを収集したり、複数のリモートマシンでメンテナンスタスクを自動化したりすることが挙げられます。

他のPowerShell機能と再利用可能なセッションを組み合わせてください。時間を節約し、手動の介入を減らすために、IT管理と自動化の取り組みを効率化してください。

Source:
https://adamtheautomator.com/powershell-reusable-sessions/