勉強会キット Windows PowerShell 4.0 による Windows Server 2012 R2 の管理 ~ Hyper-V 編 第一版 2013.12.01 日本マイクロソフト株式会社 エバンジェリスト 安納 順一 Junichi Anno BLOG http://blogs.technet.com/junichia/ 1 はじめに この勉強会キットでは、Windows PowerShell を使用してリモートコンピューターから Hyper-V を管理するための手法を学習します。 演習では Windows Server 2012 R2 と Hyper-V Server 2012 R2 を使用していますが、多 くの操作は旧バージョンの OS でも動作します。 この勉強会キットは3部構成になっています。 第1部 基本的な操作方法 このセクションではインストール直後の OS を、PowerShell のコマンドレットだけ を使用して Hyper-V が使用できるように環境設定していきます。 第2部 ライブマイグレーション このセクションでは、第1部でセットアップした Hyper-V 環境にさらに手を入れてラ イブマイグレーションが実行できるようにします。 第3部 Windows PowerShell エキスパートを目指す方へ 第1部、第2部では細かな技術解説は行っていません。このセクションでは、Windows PowrShell の細かいテクニックも含め、Windows Server 全般を管理するためのスクリ プトを作成するのに必要なテクニックについて解説しています。 2 事前準備 本勉強会キットの手順書に沿って学習する場合には、事前に以下の環境を準備してください。 なお、ホスト名やIPアドレスは演習中に Windows PowerShell コマンドレットを使用して 設定するので、事前設定は必要ありません。 いずれの OS も以下よりダウンロードできます (OSがインストールされたVHDファイルもダウンロードできます) http://technet.microsoft.com/ja-jp/evalcenter/dn205286.aspx 物理マシン Windows Server 2012 R2 (GUI使用サーバー) 物理マシン Hyper-V Server 2012 R2 Sysprep済の 仮想ハードディスク Windows Server 2012 R2 第1部で使用 第2部で使用 ライブマイグレーションを行う場合には2台の物理サーバーが必要です 3 Agenda 第1部 基本的な操作方法 このセクションではインストール直後の OS を、PowerShell のコマンドレットだ けを使用して Hyper-V が使用できるように環境設定していきます。 第2部 ライブマイグレーション このセクションでは、第1部でセットアップした Hyper-V 環境にさらに手を入れ てライブマイグレーションが実行できるようにします。 第3部 Windows PowerShell エキスパートを目指す方へ 第1部、第2部では細かな技術解説は行っていません。このセクションでは、 Windows PowrShell の細かいテクニックも含め、Windows Server 全般を管理する ためのスクリプトを作成するのに必要なテクニックについて解説しています。 4 第1部 基本的な操作を学ぼう このセクションでは、OS インストール直後の状態から、Windows PowerShell だけを使用して、Hyper-V 上に仮想マシンを立ち上げます。 5 1台目の Windows Server 1. Windows Server 2012 R2 のインストール 2. Windows PowerShell の基本設定 統合スクリプト環境の起動 実行ポリシーの設定 リモーティングの設定 3. 4. Windows Server の基本設定 IP アドレスの設定 DNS の設定 ローカルコンピューター名の設定 Windows Update の実行 Hyper-V の構成 Hyper-V 役割のインストール Hyper-V ホストの規定値を変更する 仮想ハードディスクの保存先 仮想マシンの保存先 Hyper-V レプリカの有効化 仮想スイッチの作成 5. DNS サーバーの構成 DNS サーバー役割のインストール DNS ゾーンの確認 6. Active Directory ドメインの構成 AD DS 役割のインストール Active Directory ドメインの構築 7. DHCP Server の構成 DHCP サービスのインストール DHCP サービスを構成する スコープを作成する 8. 仮想マシンの構成 ゲスト OS の作成 ゲスト OS の初期設定 ゲスト OS の環境設定 6 1.Windows Server 2012 R2 のインストール ① Windows Server 2012 R2 を「GUI付き」で普通にインストール してください。ここでは Windows PowerShell は使用しません。 以降の手順で Windows PowerShell を使用して環境設定を行い ます。 7 2. Windows PowerShell の基本設定 統合スクリプト環境の起動 ① Windows Server 2012 R2 にサインインする ② デスクトップのタスクバーに登録されている Windows PowerShell アイコンをク リックして PowerShell コンソールを起動する。 ③ 一度コンソールを閉じる ④ Windows PowerShell アイコンを「右クリック」して「ISE を管理者として実行 する」を選択し、ISE(統合スクリプト環境)を起動する。 スクリプトエディタ スクリプト実行画面 コマンドレットを直接実行 コ マ ン 文字が小さい場合には ド [Ctrl]+[+] で拡大できます。 レ [Ctrl] + [-] で縮小できます。 ッ ト 検 索 8 実行ポリシーの設定 ① 以下のコマンドレットを実行し、ローカルで作成したスクリプトは署名なしで実行 できるように実行ポリシーを変更する PS C:\>Set-ExecutionPolicy RemoteSigned リモーティングの有効化 ① 以下のコマンドレットを実行し、PowerShell によるリモート管理を有効にする PS C:\>Enable-PSRemoting –force 9 3. Windows Server の基本設定 IP アドレスの設定 ① ネットワークアダプタの一覧を表示し、IPアドレスを設定するネットワークカードの InterfaceIndex を特定する PS C:\> Get-NetAdapter | FT Name, InterfaceIndex, InterfaceDescription ② ターゲットとなるネットワークアダプターの情報を確認する(以下の例では InterfaceIndex = 13 としている) PS C:\> Get-NetIPAddress -InterfaceIndex 13 -AddressFamily IPv4 ③ 既定では DHCP を利用するように設定されているので、以下のコマンドを使用して静的な IP アドレスを設定する PS C:\>New-NetIPAddress -InterfaceIndex 13 -IPAddress 192.168.0.1 -AddressFamily IPv4 -PrefixLength 24 -DefaultGateway 192.168.0.254 ※ DefaultGateway は必要に応じて ※ 既存の静的アドレスを変更する場合には Set-NetIPAddress を使用する 10 DNS の設定 ① DNS サーバーのアドレスを設定する PS C:\>Set-DnsClientServerAddress -Interface 24 -ServerAddress 192.168.0.1 ※ 複数の DNS サーバーが存在する場合にはカンマで区切って指定する 参考 IP アドレスの削除 PS C:\> Remove-IPAddress -InterfaceIndex 24 -AddressFamily IPv4 DNSの設定を削除する PS C:\> Set-DnsClientServerAddress -Interface 24 -ResetServerAddress DHCP を有効にする PS C:\> Set-NetIPInterface -InterfaceIndex 24 -Dhcp Enabled 11 ローカルコンピューター名を設定する ① 現在のコンピューター名を取得する PS C:\> $Env:ComputerName ② 新しいコンピューター名を設定し、再起動する PS C:\> Rename-Computer -NewName “HV01” -Force -Restart 12 Windows Update を実行する ① 以下のコマンドを実行して、Windows Update PowerShell Module をダウンロードする PS C:\> $web = New-Object System.Net.WebClient PS C:\> $zipfile = "http://gallery.technet.microsoft.com/scriptcenter/” PS C:\> $zipfile = $zipfile + “2d191bcd-3308-4edd-9de2-88dff796b0bc/file/41459/28/PSWindowsUpdate.zip" PS C:\> $web.DownloadFile($zipfile, "C:\tmp\PSWindowsUpdate.zip") 上記コマンドでダウンロードできない場合には、以下のサイトから Windows Update PowerShell Module の最新版をダウンロードしてください http://gallery.technet.microsoft.com/scriptcenter/2d191bcd-3308-4edd-9de2-88dff796b0bc ※「Windows Update PowerShell Modules」で検索すればヒットします ② 以下のコマンドを使用して、ダウンロードした PSWindowsUpdate.zip ファイルを適当な場所に 展開する。ここでは C:\tmp フォルダに展開しています。 PS C:\> Add-Type -AssemblyName System.IO.Compression.FileSystem PS C:\> $ZipFile = Get-Item C:\tmp\PSWindowsUpdate.zip PS C:\> [IO.Compression.ZipFile]::ExtractToDirectory( $ZipFile, ‘C:\tmp’ ) ③ Dir コマンドで、 PSWindowsUpdate フォルダが作成されていることを確認 13 ④ 以下のコマンドを実行し、フォルダの中に格納されているすべてのファイルの「ブロック 解除」を行う。この操作はファイルのプロパティ画面から「ブロックの解除」を行うのと 同様である。 PS C:\>Unblock-File <ファイルの保存先>\*.* (例) PS C:\>Unblock-File c:\tmp\PSWindowsUpdate\*.* ⑤ PowerShell モジュールの格納場所を確認する PS C:\>$env:PSModulePath C:\Users\Administrator\Documents\WindowsPowerShell\Modules;C:\windows\system32\Window sPowerShell\v1.0\Modules\;C:\Program Files (x86)\Microsoft SDKs\Windows Azure\PowerShell\ ⑥ 既定では C:\Users\junichia\Documents\WindowsPowerShell\Modules が存在しない ので、以下のコマンドで PowerShell モジュールの格納場所を作成する PS C:\> md C:\Users\Administrator\Documents\WindowsPowerShell\Modules 14 ⑦ 以下のコマンドを実行し PSWindowsUpdate フォルダーを C:\Users\Administrator\Documents\WindowsPowerShell\Modules 配下に移動する 以下の例では PSWindowsUpdate フォルダーは C:\tmp にあるものとしている PS C:\> Move C:\tmp\PSWindowsUpdate C:\Users\Administrator\Documents \WindowsPowerShell\Modules ⑧ PSWindowsUpdate モジュールを読み込む PS C:\> Import-Module PSWindowsUpdate ⑨ Windows Update を実行する PS C:\> Get-WUInstall -AcceptAll 15 4. Hyper-V の構成 Hyper-V 役割をインストールする ① 以下のコマンドで現在インストールされている役割と機能の一覧を参照する PS C:\> Get-WindowsFeature ② 以下のコマンドを実行して、Hyper-V 役割と管理ツール群をインストールし再起動する PS C:\> Add-WindowsFeature Hyper-V -IncrudeAllSubFeature -IncludeManagementTools -Restart ③ Hyper-V 関連のコマンドレットを確認する PS C:\> Get-Command -Module Hyper-V 16 Hyper-V ホストの設定値を変更する ① Hyper-V ホストの規定値を確認する PS C:\> Get-VMHost | FL ② 仮想ハードディスクの既定の保存先を設定する ※以下の例では仮想ハードディスクの既定の保存先を D:\VM に指定しています PS C:\> Set-VMHost -VirtualHardDiskPath D:\VM ③ 仮想ハードディスクの構成ファイルの既定の保存先を設定する PS C:\> Set-VMHost -VirtualMachinePath D:\VM 17 Hyper-Vレプリカを有効にする ① Hyper-V レプリカの設定値を確認する PS C:\> Get-VMReplicationServer | FL ② Hyper-V レプリカを有効にし、認証タイプを Kerberos にする PS C:\> Set-VMReplicationServer -ReplicationEnabled $True -AllowedAuthenticationType Kerberos ③ どんなサーバーからの複製も受け入れ、複製の保存先を D:\VM に設定する PS C:\> Set-VMReplicationServer -ReplicationAllowedFromAnyServer $True -DefaultStorageLocation D:\VM ④ Windows Firewall の受信規則を確認する PS C:\> Get-NetFirewallRule -Direction Inbound 18 ⑤ Windows Firewall の受信規則の中から、Hyper-V レプリカに関する設定を確認する PS C:\> Get-NetFirewallRule -Direction Inbound -Desctiption *レプリカ* ※ HTTP と HTTPS に関する規則が存在することがわかります ※ それぞれ、ルール名で保存されています HTTP : VIRT-HVRHHTTPL-In-TCP-NoScope HTTPS : VIRT-HVRHHTTPSL-In-TCP-NoScope ⑥ “Hyper-V レプリカ HTTP リスナー(TCP受信)”規則を有効にする PS C:\> Set-NetFirewallRule -Name “VIRT-HVRHTTPL-In-TCP-NoScope” -Enabled True $ は必要ありません 19 仮想スイッチの作成 ① 仮想スイッチの一覧を表示する PS C:\> Get-VMSwitch ※まだ仮想スイッチは存在しません ② ネットワークアダプターの一覧を表示し、外部仮想スイッチにバインドするネットワーク アダプターの Name 値を確認する PS C:\> Get-NetAdapter | FL ③ 新しい外部スイッチを “ExternalSwitch” という名前で作成する。以下の例ではバインド 先のネットワークアダプタ名は“イーサネット”として指定している。 PS C:\> New-VMSwitch -Name “ExternalSwitch” -NetAdapterInterName “イーサネット” -AllowManagementOS $True ④ ②で確認したHyper-V ホストの NIC が仮想化され、“ExternalSwitch”に接続されたこと を確認する PS C:\> Get-NetAdapter | FL ※ “vEthernet (ExternalSwitch)” という仮想NIC が新たに作成されたことを確認してく ださい 20 5. DNS サーバーを構成する DNSサーバー役割をインストールする ① DNS をインストールする PS C:\> Add-WindowsFeature dns -IncludeManagementTools -IncrudeAllSubFeature -Restart ② DNS サービス関連のコマンドレットを確認する PS C:\> Get-Command *DNSServer* DNS ゾーン の確認 ① 現在のゾーン設定を確認する PS C:\> Get-DNSServerZone 現時点ではゾーンは存在しません。以降の手順でActive Directory ドメインを構築します。 21 6. Active Directory ドメインを構成する Active Directory Domain Service (AD DS)役割をインストールする ① AD DS をインストールする PS C:\> Add-WindowsFeature AD-Domain-Services -IncludeManagementTools -IncrudeAllSubFeature -Restart ② AD DS 関連のコマンドレットを確認する PS C:\> Get-Command -module ActiveDirectory Active Directory ドメインを構築する ここでは Contoso.com ドメインを作成します ① 必要なモジュールをインポートする PS C:\> Import-Module ADDSDeployment ② 以下のコマンドを実行して回復モードパスワードを SecureString に変換し、$Password 変数に格納する。ここではパスワードを P@ssw0rd としています。 PS C:\> $Password = ConvertTo-SecureString “P@ssw0rd” -AsPlainText -Force 22 ③ ドメインコントローラーに昇格する ※ 以下は便宜上改行していますが、実際には1行で入力してください PS C:\> Install-ADDSForest -CreateDnsDelegation:$False -DatabasePath “C:\Windows\NTDS” -DomainMode “Win2012R2” -DomainName “contoso.com” -DomainNetbiosName “CONTOSO” -ForestMode “Win2012R2” -InstallDns:$True -LogPath C:\Windows\NTDS” -NoRebootOnCompletion:$False -SysvolPath “C:\Windows\Sysvol” -SafeModeAdministratorPassword $Password -Force:$True インストールが完了すると自動的に再起動されます。 23 ④ Contoso.com ゾーンが作成されていることを確認する PS C:\> Get-DNSServerZone -Name contoso.com | FL 24 7. DHCP サーバーを構成する DHCP サービスをインストールする 今後仮想マシンを作成した際にアドレスをリースできるようにするため、DHCPサーバーを セットアップしておきます。 ① 以下のコマンドで DHCP サービスをインストールする PS C:\> Add-WindowsFeature DHCP -IncrudeAllSubFeature -IncludeManagementTools -Restart ※ -Restart パラメタは、再起動が必要な場合に限って再起動が行われます。DHCPサービスのインストールでは再起動は 行われません。 ② DHCPサービス関連のコマンドレットを確認する PS C:\> Get-Command *DHCP* 25 DHCP サービスを構成する ① DHCP サーバーのバインディングが 192.168.0.1 に設定されていることを確認する ※バインディングが有効にされた NIC を通じて DHCP サービスによる IP アドレスリースが行われます PS C:\> Get-DHCPServerV4Binding BindingState が True であることを確認してください。 ② DHCP サービスのバインディングを 192.168.0.1 に設定する(設定されていない場合) ※事前に Get-NetAdapter で NIC の Name プロパティを確認してください。以下の例で -InterfaceAlias に指定している値は NIC の Name プロパティです。 PS C:\>Set-DHCPServerV4Binding -InterfaceAlias “vEthernet (ExternalSwitch)” -BindingState $True ③ DHCP サービスを Active Directory で承認する PS C:\> Add-DHCPServerInDC -DnsName contoso.com ④ DHCP サービスに必要なセキュリティグループを作成する ※Netsh コマンドを使用します PS C:\> Netsh dhcp add SecurityGroups 26 ⑤ DHCP サービスを再起動 PS C:\> Restart-Service DHCPServer ⑥ もしサーバーマネージャー上に「DHCP サーバーの構成が必要です」が表示され続けるよ うであれば、以下のコマンドを実行してアラートをリセットする PS C:\> Set-ItemProperty –Path registry::HKLM\SOFTWARE\Microsoft\ServerManager\Roles\12 –Name ConfigurationState –Value 2 27 スコープを作成する ① IPV4 のスコープを追加 PS C:\>Add-DHCPServerV4Scope -StartRange 192.168.0.10 -EndRange 192.168.0.20 -SubnetMask 255.255.255.0 -Name “Scope for VMs” -State Active ② 追加したスコープを表示し、Scope ID を確認する ※ この演習では 192.168.0.0 と設定されているはず PS C:\>Get-DHCPServerV4Scope ③ 作成したスコープに DNS Server を追加する PS C:\> Set-DhcpServerV4ScopeOptionValue -ScopeID 192.168.0.0 -DnsServer 192.168.0.1 28 8. 仮想マシンの構成 ここでは既に OS がインストールされている仮想ハードディスクを使用して、新しいゲ ストOSを作成します ゲスト OS の作成 ① ゲストOSの一覧を取得する ※何も表示されません PS C:\> Get-VM ② ゲストOS を作成する この例では VM01 という名前のゲストOSを作成します。仮想マシンの世代は「第一世代」 としています。また、仮想ハードディスクの保存先は D:\VMs\VM01.vhd です。 PS C:\> New-VM -Name “VM01” -MemoryStartupBytes 1024MB -VHDPath D:\VMs\VM01.vhd -SwitchName “ExternalSwitch” -Generation 1 -BootDevice IDE 29 ③ 作成したゲストOS VM01 の設定値を確認する PS C:\> Get-VM -Name VM01 | FL ④ 動的メモリを有効にし、仮想CPUの割り当て数を 2 に変更する PS C:\> Set-VM -Name VM01 -ProcessorCount 2 -DynamicMemory ⑤ ゲストOSを起動する PS C:\> Start-VM VM01 30 ゲスト OS の初期設定(この部分だけゲストOS側で実施します) この演習では、ゲスト OS として Sysprep が適用された Windows Server 2012 R2 を使用しています。 ※評価版ダウンロードサイトからダウンロードした「VHD」ファイル そのため、リモート(Hyper-V ホスト)からの管理を有効にするには、Hyper-V マネージャーからゲスト OS 「VM01」に接続して、以下の操作を行う必要があります。 • • OOBE セットアップ • 言語の選択(規定値は英語です) • 利用許諾への合意 • パスワードの設定(言語で En-US を選択した場合、キーボード配列は 101/102 となります。ご 注意ください) パスワードとして P@ssw0rd を使用する場合、 101/102 キーボードの場合、「@」は [Shift] + [2] となります。 ゲストOSの PowerShell コンソールから以下を実行してリモーティングを有効化 PS C:\> Enable-PSRemoting -Force • ゲストOS の PowerShell コンソールから ネットワーク探索を有効化 PS C:\> netsh advfirewall firewall set rule group=”network discovery” new enable=yes 31 ゲスト OS の環境設定を行う ※この操作は Hyper-V ホスト側でおこないます ① ゲストOSをリモート管理するために、Hyper-V ホスト側の TrustedHosts の設定を行う PS C:\> Set-Item WSMan:\localhost\Client\TrustedHosts 192.168.0.* -Concatenate ② ゲストOSに接続するための資格情報を作成する ※ここではゲストOSのパスワードが P@ssw0rd であるとします PS C:\> $User = “Administrator” PS C:\> $Pass = ConvertTo-SecureString “P@ssw0rd” -AsPlainText -Force PS C:\> $Cred = New-Object System.Management.Automation.PSCredential $user, $pass ③ ゲストOSにリースされているIPアドレスを確認する PS C:\> Get-DhcpServerV4Lease -ScopeId 192.168.0.0 ④ 作成したクレデンシャルを使用して、ゲストOSに接続する ※ ゲストOS VM01 には、DHCPサーバーより 192.168.0.11 がリースされているものとします PS C:\> Enter-PSSession 192.168.0.11 -Credential $Cred 32 ⑤ ゲストOS のネットワークアダプター情報を確認する (InterfaceIndex を確認してください) ※ゲストOSのセッションに接続したまま実行します [192.168.0.11] :PS C:\> Get-NetAapter ⑥ ゲストOS のIPアドレスを確認する(InterfaceIndex = 12 としています) ※PrefixOrigin が DHCPであることを確認してください ※ゲストOSのセッションに接続したまま実行します [192.168.0.11] :PS C:\> Get-NetIPAddress -InterfaceIndex 12 -AddressFamily IPv4 ⑦ ゲスト OS の IP アドレスを 192.168.0.100 に設定する ※ゲストOSのセッションに接続したまま実行します [192.168.0.11] :PS C:\> New-NetIPAddress -InterfaceIndex 12 -IPAddress 192.168.0.100 -AddressFamily IPv4 -PrefixLength 24 このコマンドを実行すると ゲストOSのIPアドレス変更によってセッションが切断されます。 これは正しい動作です。自動的に再接続が試みられますが、[Ctrl]+[C] でキャンセルして ください。 33 ⑧ 再度ゲストOSに接続する PS C:\> $User = “Administrator” PS C:\> $Pass = ConvertTo-SecureString “P@ssw0rd” -AsPlainText -Force PS C:\> $Cred = New-Object System.Management.Automation.PSCredential $user, $pass PS C:\> Enter-PSSession 192.168.0.100 -Credential $Cred [192.168.0.100] :PS C:\> ⑨ DNSサーバーの設定を行う ※ゲストOSのセッションに接続したまま実行します [192.168.0.100] PS C:\>Set-DnsClientServerAddress -Interface 12 -ServerAddress 192.168.0.1 ⑩ コンピューター名を変更する ※ゲストOSのセッションに接続したまま実行します [192.168.0.100] :PS C:\> Rename-Computer -NewName “HV01” -Force -Restart ⑪ セッションを閉じる [192.168.0.100] :PS C:\> Exit PS C:\> 34 ⑫ VM01 を DNS に登録する PS C:\> Add-DnsServerResourceRecordA -Name VM01 -IPAddress 192.168.0.100 -ZoneName contoso.com ⑬ 再度ゲストOSに接続する PS C:\> $User = “Administrator” PS C:\> $Pass = ConvertTo-SecureString “P@ssw0rd” -AsPlainText -Force PS C:\> $Cred = New-Object System.Management.Automation.PSCredential $user, $pass PS C:\> Enter-PSSession 192.168.0.100 -Credential $Cred [192.168.0.100] :PS C:\> 35 ⑫ VM01 を ドメインに参加させる ※ゲストOSのセッションに接続したまま実行します [192.168.0.100] :PS C:\> $Domain = “contoso.com” [192.168.0.100] :PS C:\> $Client = $Env:COMPUTERNAME [192.168.0.100] :PS C:\> $User = “Administrator” [192.168.0.100] :PS C:\> $Pass = ConvertTo-SecureString “P@ssw0rd” -AsPlainText -Force [192.168.0.100] :PS C:\> $Cred = New-Object System.Management.Automation.PSCredential $user , $pass [192.168.0.100] :PS C:\> $DomainUser = “Contoso\Administrator” [192.168.0.100] :PS C:\> $DomainPass = ConvertTo-SecureString “P@ssw0rd” -AsPlainText -Force [192.168.0.100] :PS C:\> $DomainCred = New-Object System.Management.Automation.PSCredential $DomainUser , $DomainPass [192.168.0.100] :PS C:\> Add-Computer -ComputerName $Clienit -LocalCredential $Cred -Credential $DomainCred -DomainName $Domain ⑬ セッションを閉じる [192.168.0.100] :PS C:\> Exit PS C:\> 36 ⑫ 仮想マシン VM01 を再起動する PS C:\> Restart-VM VM01 -Force ⑬ 資格情報なしで VM01 に接続できることを確認する PS C:\> Enter-PSSession VM01 [VM01]: PS C:\> ⑭ セッションを閉じる [VM01]: PS C:\> Exit PS C:\> 37 第2部 ライブマイグレーション このセクションでは、第1部で作成した環境に Hyper-V サーバーをもう1台加 え、ライブマイグレーションが行える環境を構築します。 もちろん、各種設定は Windows PowerShell のみで行います。 38 以降の作業ではライブマイグレーションを行うため、Hyper-V がインストールされた2台目 の Windows Server が必要となります。ここでは、Hyper-V Server 2012 R2 を使用してい ます。 2台目の Windows Server 9. Hyper-V Server 2012 R2 のインストール 10. Windows PowerShell の基本設定 実行ポリシーの設定 リモーティング(リモート管理)の設定 11. Windows Server の基本設定 IP アドレスの設定 DNS の設定 コンピューター名の設定 Active Directory ドメインへの参加 Windows Update の実行 12. Hyper-V の構成 PowerShell モジュールのインストール Hyper-V ホストの規定値を変更する • 仮想ハードディスクの保存先 • 仮想マシンの保存先 Hyper-V レプリカの有効化 仮想スイッチの作成 ライブマイグレーションの設定を実行 ※1台目のサーバー HV01 で実施 13. ライブマイグレーションの環境設定 ライブマイグレーションの有効化 仮想マシンの「プロセッサの互換性」の設定 委任の設定 14. ライブマイグレーションの実行 39 9. Hyper-V Server 2012 R2 のインストール 2台目の PC を用意し、Hyper-V がインストールされた Windows Server 2012 R2 を用意してください。 ここでは Hyper-V Server 2012 R2 を使用します。 Hyper-V Server 2012 R2 をインストールすると自動的に Hyper-V もイ ンストールされます。 40 10. Windows PowerShell の基本設定 Hype-V Server 2012 R2 では統合スクリプト環境(ISE)を使用することはできません。 スクリプト環境の起動 ① Hyper-V Server 2012 R2 にサインインする ② コマンドプロンプトで以下のコマンドを実行して PowerShell コンソールを起動する。プロン プトが 「PS」に変わったことを確認してください。 C:\> PowerShell PS C:\> 実行ポリシーの設定 ① 以下のコマンドレットを実行し、ローカルで作成したスクリプトは署名なしで実行できるよう に実行ポリシーを変更する PS C:\>Set-ExecutionPolicy RemoteSigned リモーティングの有効化 ① 以下のコマンドレットを実行し、PowerShell によるリモート管理を有効にする PS C:\>Enable-PSRemoting –force 41 11. Hyper-V Server の基本設定 IP アドレスの設定 ① ネットワークアダプタの一覧を表示し、IPアドレスを設定するネットワークカードの InterfaceIndex を特定する PS C:\> Get-NetAdapter | FT Name, InterfaceIndex, InterfaceDescription ② ターゲットとなるネットワークアダプターの情報を確認する(以下の例では InterfaceIndex = 13 としている) PS C:\> Get-NetIPAddress -InterfaceIndex 13 -AddressFamily IPv4 ③ 既定では DHCP を利用するように設定されているので、以下のコマンドを使用して静的な IP アドレスを設定する PS C:\>New-NetIPAddress -InterfaceIndex 13 -IPAddress 192.168.0.2 -AddressFamily IPv4 -PrefixLength 24 ※ DefaultGateway は必要に応じて ※ 既存の静的アドレスを変更する場合には Set-NetIPAddress を使用する 42 DNS の設定 ① DNS サーバーのアドレスを設定する PS C:\>Set-DnsClientServerAddress -Interface 13 -ServerAddress 192.168.0.1 ※ 複数の DNS サーバーが存在する場合にはカンマで区切って指定する 参考 IP アドレスの削除 PS C:\> Remove-IPAddress -InterfaceIndex 24 -AddressFamily IPv4 DNSの設定を削除する PS C:\> Set-DnsClientServerAddress -Interface 24 -ResetServerAddress DHCP を有効にする PS C:\> Set-NetIPInterface -InterfaceIndex 24 -Dhcp Enabled 43 ローカルコンピューター名を設定する ① 現在のコンピューター名を取得する PS C:\> $Env:ComputerName ② 新しいコンピューター名を設定し、再起動する PS C:\> Rename-Computer -NewName “HV02” -Force -Restart ③ 再起動後サインインして、再度 PowerShell コンソールを起動する C:\> PowerShell PS C:\> 44 Hyper-V Server “HV02” を Contoso ドメインに参加させる ① ドメインに参加させる PS C:\> $Domain = “contoso.com” PS C:\> $Client = $Env:COMPUTERNAME PS C:\> $User = “Administrator” PS C:\> $Pass = ConvertTo-SecureString “P@ssw0rd” -AsPlainText -Force PS C:\> $Cred = New-Object System.Management.Automation.PSCredential $user , $pass PS C:\> $DomainUser = “Contoso\Administrator” PS C:\> $DomainPass = ConvertTo-SecureString “P@ssw0rd” -AsPlainText -Force PS C:\> $DomainCred = New-Object System.Management.Automation.PSCredential $DomainUser , $DomainPass PS C:\> Add-Computer -ComputerName $Clienit -LocalCredential $Cred -Credential $DomainCred -DomainName $Domain ② コンピューターを再起動する PS C:\> Restert-Computer ③ 再起動後、ドメインアカウント(contoso\administrator)でサインインしてください 45 Windows Update を実行する ① 以下のコマンドを実行して、Windows Update PowerShell Module をダウンロードする PS C:\> $web = New-Object System.Net.WebClient PS C:\> $zipfile = "http://gallery.technet.microsoft.com/scriptcenter/” PS C:\> $zipfile = $zipfile + “2d191bcd-3308-4edd-9de2-88dff796b0bc/file/41459/28/PSWindowsUpdate.zip" PS C:\> $web.DownloadFile($zipfile, "C:\tmp\PSWindowsUpdate.zip") 上記コマンドでダウンロードできない場合には、以下のサイトから Windows Update PowerShell Module の最新版をダウンロードしてください http://gallery.technet.microsoft.com/scriptcenter/2d191bcd-3308-4edd-9de2-88dff796b0bc ※「Windows Update PowerShell Modules」で検索すればヒットします ② 以下のコマンドを使用して、ダウンロードした PSWindowsUpdate.zip ファイルを適当な場所に 展開する。ここでは C:\tmp フォルダに展開しています。 PS C:\> Add-Type -AssemblyName System.IO.Compression.FileSystem PS C:\> $ZipFile = Get-Item C:\tmp\PSWindowsUpdate.zip PS C:\> [IO.Compression.ZipFile]::ExtractToDirectory( $ZipFile, ‘C:\tmp’ ) ③ Dir コマンドで、 PSWindowsUpdate フォルダが作成されていることを確認 46 ④ 以下のコマンドを実行し、フォルダの中に格納されているすべてのファイルの「ブロック 解除」を行う。この操作はファイルのプロパティ画面から「ブロックの解除」を行うのと 同様である。 PS C:\>Unblock-File <ファイルの保存先>\*.* (例) PS C:\>Unblock-File c:\tmp\PSWindowsUpdate\*.* ⑤ PowerShell モジュールの格納場所を確認する PS C:\>$env:PSModulePath C:\Users\Administrator\Documents\WindowsPowerShell\Modules;C:\windows\system32\Window sPowerShell\v1.0\Modules\;C:\Program Files (x86)\Microsoft SDKs\Windows Azure\PowerShell\ ⑥ 既定では C:\Users\junichia\Documents\WindowsPowerShell\Modules が存在しない ので、以下のコマンドで PowerShell モジュールの格納場所を作成する PS C:\> md C:\Users\Administrator\Documents\WindowsPowerShell\Modules 47 ⑦ 以下のコマンドを実行し PSWindowsUpdate フォルダーを C:\Users\Administrator\Documents\WindowsPowerShell\Modules 配下に移動する 以下の例では PSWindowsUpdate フォルダーは C:\tmp にあるものとしている PS C:\> Move C:\tmp\PSWindowsUpdate C:\Users\Administrator\Documents \WindowsPowerShell\Modules ⑧ PSWindowsUpdate モジュールを読み込む PS C:\> Import-Module PSWindowsUpdate ⑨ Windows Update を実行する PS C:\> Get-WUInstall -AcceptAll 48 12. Hyper-V の構成 Hyper-V Server には既にHyper-Vの役割がインストールされていますが、PowerShell 管理 用モジュールはインストールされていません。ここでは管理モジュールをインストールします。 Windows PowerShell 用 Hyper-V モジュールをインストールする ① 以下のコマンドで現在インストールされている役割と機能の一覧を参照する PS C:\> Get-WindowsFeature ② 以下のコマンドを実行して、Windows PowerShell 用 Hyper-V モジュールをインストー ルする PS C:\> Add-WindowsFeature Hyper-V-PowerShell -IncludeAllSubFeature ③ Hyper-V 関連のコマンドレットを確認する PS C:\> Get-Command -Module Hyper-V 49 Hyper-V ホストの設定値を変更する ① Hyper-V ホストの規定値を確認する PS C:\> Get-VMHost | FL ② 仮想ハードディスクの既定の保存先を設定する ※以下の例では仮想ハードディスクの既定の保存先を E:\VM に指定しています PS C:\> Set-VMHost -VirtualHardDiskPath E:\VM ③ 仮想ハードディスクの構成ファイルの既定の保存先を設定する PS C:\> Set-VMHost -VirtualMachinePath E:\VM 50 Hyper-Vレプリカを有効にする ① Hyper-V レプリカの設定値を確認する PS C:\> Get-VMReplicationServer | FL ② Hyper-V レプリカを有効にし、認証タイプを Kerberos にする PS C:\> Set-VMReplicationServer -ReplicationEnabled $True -AllowedAuthenticationType Kerberos ③ どんなサーバーからの複製も受け入れ、複製の保存先を E:\VM に設定する PS C:\> Set-VMReplicationServer -ReplicationAllowedFromAnyServer $True -DefaultStorageLocation E:\VM ④ Windows Firewall の受信規則を確認する PS C:\> Get-NetFirewallRule -Direction Inbound 51 ⑤ Windows Firewall の受信規則の中から、Hyper-V レプリカに関する設定を確認する PS C:\> Get-NetFirewallRule -Direction Inbound -Desctiption *レプリカ* ※ HTTP と HTTPS に関する規則が存在することがわかります ※ それぞれ、ルール名で保存されています HTTP : VIRT-HVRHHTTPL-In-TCP-NoScope HTTPS : VIRT-HVRHHTTPSL-In-TCP-NoScope ⑥ “Hyper-V レプリカ HTTP リスナー(TCP受信)”規則を有効にする PS C:\> Set-NetFirewallRule -Name “VIRT-HVRHTTPL-In-TCP-NoScope” -Enabled True $ は必要ありません 52 仮想スイッチの作成 ライブマイグレーションを実行するには、HV01と同じ名前の仮想スイッチを作成しておく必 要があります) ① ネットワークアダプターの一覧を表示し、外部仮想スイッチにバインドするネットワーク アダプターの Name 値を確認する PS C:\> Get-NetAdapter | FL ② 新しい外部スイッチを “ExternalSwitch” という名前で作成する。以下の例ではバインド 先のネットワークアダプタ名は“イーサネット”として指定している。 PS C:\> New-VMSwitch -Name “ExternalSwitch” -NetAdapterInterName “イーサネット” -AllowManagementOS $True ③ ②で確認したHyper-V ホストの NIC が仮想化され、“ExternalSwitch”に接続されたこと を確認する PS C:\> Get-NetAdapter | FL ※ “vEthernet (ExternalSwitch)” という仮想NIC が新たに作成されたことを確認してく ださい 53 ⑤ 仮想スイッチ ExternalSwitch が作成されたことを確認する PS C:\> Get-VMSwitch 54 13.ライブマイグレーションの有効化と実行 ここまでの作業で以下のような環境が構築できました。 ここからは HV01 と HV02 間でライブマイグレーションを行うための設定をしていきます。 ここからの作業は HV01 上の PowerShell ISE から実行します。 Active Directory ドメイン Contoso.com 物理マシン 物理マシン Windows Server 2012 R2 Hyper-V Server 2012 R2 (GUI使用サーバー) HV01 192.168.0.1 • • • • Hyper-V AD DS DNS DHCP 仮想スイッチ ExternalSwitch 仮想マシン Windows Server 2012 R2 VM01 192.168.0.3 HV02 192.168.0.2 • Hyper-V 仮想スイッチ ExternalSwitch 55 ここからの作業は HV01 上から実行します。 Hyper-V ホストのライブマイグレーションを有効にする ① HV01 と HV02 のライブマイグレーションを有効にする PS C:\> Enable-VMMigration -ComputerName HV01, HV02 ② 任意のネットワークカードを使用してライブマイグレーションを受信できるようにする Set-VMHost -ComputerName HV01, HV02 -UseAnyNetworkForMigration $True ③ パフォーマンスオプションを「圧縮」モードに設定する Set-VMHost -ComputerName HV01, HV02 -VirtualMachineMigrationPerformanceOption Compression ④ ライブマイグレーションの認証プロトコルを「Kerberos」に設定する Set-VMHost -ComputerName HV01, HV02 -VirtualMachineMigrationAuthenticationType Kerberos 56 ⑤ 同時に移行できる仮想マシンの数を 10 に変更する PC C:\> Set-VMHost -ComputerName HV01, HV02 -MaximumVirtualMachineMigrations 10 移行の対象となる仮想マシンの「プロセッサの互換性」を設定する ライブマイグレーションに使用する物理コンピューターが異なるプロセッサバージョンを搭載している場 合には、仮想マシンごとに「プロセッサバージョンが異なる物理コンピューターへ移行する」を有効にし て置く必要があります。 ① 仮想マシンをシャットダウンする PS C:\> Stop-VM -ComputerName HV01 -Name VM01 ② HV01 上の VM01 の「プロセッサバージョンが異なる物理コンピューターへ移行する」を有効にする PS C:\> Set-VMProcessor -ComputerName HV01 -VMName VM01 -CompatibilityForMigrationEnabled $True ③ 仮想マシンを起動する PS C:\> Start-VM -ComputerName HV01 -Name VM01 57 Kerberos 委任の設定を行う 委任の設定は、ライブマイグレーションを行う全てのコンピューター間で行う必要がありま す。また、委任を許可する対象となるのは各コンピューターが持つ以下の 2 つのサービスで す。 • CIFS • Microsoft Virtual System Migration Service Hyper-V over SMB を使用している場合にはファイルサーバーの CIFS も委任の対象となる ことに注意してください。 今回は、HV01 と HV02 間での委任を許可するように設定します。 HV01 委任 HV02 CIFS CIFS Microsoft Virtual System Migration Service Microsoft Virtual System Migration Service 58 ① HV01 に HV02 CIFS サービスへの委任を許可する PS C:\> $TargetServer = “HV01” PS C:\> $TargetServerDN = (Get-ADComputer $TargetServer) PS C:\> $HVServer = Get-ADComputer HV02 PS C:\> $HVServerName = $HVServer.Name PS C:\> $HVServerDNS = $HVServer.DNSHostName PS C:\> Set-ADObject -Identity $TargetServerDN -Add @{ “msDS-AllowedToDelegateTo” = “cifs/$HVServerName”, “cifs/$HVServerDNS” } ② HV02 に HV01 CIFS サービスへの委任を許可する PS C:\> $TargetServer = “HV02” PS C:\> $TargetServerDN = (Get-ADComputer $TargetServer) PS C:\> $HVServer = Get-ADComputer HV01 PS C:\> $HVServerName = $HVServer.Name PS C:\> $HVServerDNS = $HVServer.DNSHostName PS C:\> Set-ADObject -Identity $TargetServerDN -Add @{ “msDS-AllowedToDelegateTo” = “cifs/$HVServerName”, “cifs/$HVServerDNS” } 59 ③ HV01 に HV02 Microsoft Virtual System Migration サービスへの委任を許可する PS C:\> $ServiceName = “Microsoft Virtual System Migration Service” PS C:\> $TargetServer = “HV01” PS C:\> $TargetServerDN = (Get-ADComputer $TargetServer) PS C:\> $HVServer = Get-ADComputer HV02 PS C:\> $HVServerName = $HVServer.Name PS C:\> $HVServerDNS = $HVServer.DNSHostName PS C:\> Set-ADObject -Identity $TargetServerDN -Add @{ “msDS-AllowedToDelegateTo” = “$ServiceName/$HVServerName”, “$ServiceName/$HVServerDNS” } ④ HV02 に HV01 Microsoft Virtual System Migration サービスへの委任を許可する PS C:\> $ServiceName = “Microsoft Virtual System Migration Service” PS C:\> $TargetServer = “HV02” PS C:\> $TargetServerDN = (Get-ADComputer $TargetServer) PS C:\> $HVServer = Get-ADComputer HV01 PS C:\> $HVServerName = $HVServer.Name PS C:\> $HVServerDNS = $HVServer.DNSHostName PS C:\> Set-ADObject -Identity $TargetServerDN -Add @{ “msDS-AllowedToDelegateTo” = “$ServiceName/$HVServerName”, “$ServiceName/$HVServerDNS” } 60 ⑤ HV02 を再起動する(再起動が完了するまで待ち合せる) ※委任の設定を適用するためにコンピューターを再起動する必要があります PS C:\> Restart-Computer -ComputerName HV02 -Wait -Force ⑥ HV01 を再起動する ※HV02の再起動が完了してから実行してください。 PS C:\> Restart-Computer -Force コンピューターアカウントに移行先となるストレージへのアクセス権を与える ※ライブマイグレーションはコンピューターアカウントによる処理であるため、移行先のス トレージ対してコンピューターアカウントによるフルアクセス権が必要です。 61 ライブマイグレーションを実行する 今回は共有ボリュームや共有フォルダを使用しない シェアード ナシング ライブ マイグ レーション を実行してみます。 ① 仮想マシン VM01 が HV01 上で動作していることを確認 PS C:\> Get-VM -ComputerName HV01 ② 仮想マシン VM01 を HV02 に移動する ※HV02 上の E:\VM\VM01 に仮想ハードディスクごと移動するものとします PS C:\> Move-VM -ComputerName HV01 -Name VM01 -DestinationHost HV02 -IncludeStorage -DestinationStoragePath E:\VM\VM01 統合スクリプト環境上で実行すると、画面上に移行のプログレスバーが表示されます。 ③ 仮想マシン VM01 が HV02 上で動作していることを確認する PS C:\> Get-VM -ComputerName HV01 62 第3部 エキスパートを目指す方へ ここからは、Hyper-V だけに特化した手法ではなく、Windows PowerShell の 基本的なテクニックから、バックグラウンドジョブ、ワークフローなどの高度な テクニックまでを解説します。 Visual Studioからの呼び出し方法についても解説しています。 63 第3部 ~ PowerShell エキスパートを目指す方へ Windows PowerShell には他にもさまざまなテクニックが用意されています。特に、バック グラウンドジョブの概念はシステム管理を行う上で重要です。 Part1 基礎編 1.Windows PowerShell の位置づけ 2.基本的なコマンドレットと書式の基礎 3.基本的な文法とスクリプトの作り方 4.Tips Part4 ワークフロー編 11. 12. 13. 14. Windows PowerShell Workflow とは Windows PowerShell Workflow の基礎 ワークフロー特有の記述 ワークフロージョブとデータの永続化 Part2 リモーティング編 5.リモーティングの準備と基礎 6.-ComputerNameを使用したリモート操作 7.PS セッションとは 8.コネクションの永続化と再利用可能なPSセッション 9.Windows PowerShell Web Access(PSWA) Part3 バックグラウンドジョブ 10. バックグラウンドジョブ Part5 開発者編 15. 16. 17. 18. 開発者にとっての Windows PowerShell とは 開発者のための Windows PowerShell 基礎知識 開発者として必要な情報の取得 コマンドレット以外からオブジェクトのインスタン スを作成する 19. Visual Studio(C#)から PowerShell を呼び出す 64 Part 1 基礎編 65 基礎編 1. Windows PowerShell の位置づけ 66 Windows PowerShell の位置づけ Windows Familiar – インフラエンジニアから見ると • Windows Script(WSH)に変わる管理プラットフォーム • 高機能なスクリプティング機能による自動管理 • WinRM を介したリモートサーバー管理 Windows Familiar – 開発者 から見ると • 高機能なクラスライブラリ • コーディング、テスティングの大幅なコスト削減 Non-Windows Familiar から見ると • OMI(Open Management Infrastructure)を実装したリモートサーバー • 手元のプラットフォームからリモート管理が可能 • 使い慣れた言語からリモート管理が可能 67 代表的なスクリプト言語 バッチファイル(拡張子 .bat) OSに合わせて継続的なエンハンス MS-DOS時代から使われてきたコマンドシェル上のスクリプト。脈々と現代に引き継がれて おり、利用者が多い。豊富なコマンド群によって支えられており、案外使い出がある。複数 のスクリプトを取りまとめる役割としても便利。 Visual Basic のスクリプト版。「Visual」とあるが、Visual ではない。わかりやすい文法と、 緩い規則によって根強いファンが多い。亜種として VBA もあるが微妙に文法は異なる。 Jscript(拡張子 .js) 今後エンハンスの予定は無い JavaScript のMS 実装版として、VBScript とともに登場。JavaScript を Microsoft の独自 仕様によって拡張することで、汎用性を増している。 Windows Script 今後エンハンスの予定は無い VBScript(拡張子 .vbs) PowerShell(拡張子 .ps1) いわずと知れた高機能スクリプト言語。.NET Framework が使えると言うメリットから、利 用者は爆発的に増殖中。多くの製品がPowerShell用のコマンドレットを提供しており、 Windows Script Host は Server Coreのメニュー程度でしかお目にかかれなくなりつつある。 68 スクリプトの実行環境 bat exe VBScript JScript PowerShell エンジン COM Script Engine cmd/ command PowerShell スクリプト Windows Script Host Cscript.exe Wscript.exe C O M .NET Framework Class Library CLR(共通言語ランタイム) Windows 69 コマンドシェルの進化と機能の包含 DOS/ Win31 Win9x/ Me NT 2000 XP/2003 Vista/2008 Win7/ 2008R2 8 低機能 command.com cmd.exe Windows Script Host 高機能 PowerShell 上では bat/vbs/js も実行可能 100 Windows PowerShell コマンドレットの数 200 約 2300 70 VBScript vs PowerShell メール ボックス 統計 Exchange 2003 (VBScript) Exchange 2007(PowerShell) Set listExchange_Mailboxs = GetObject("winmgmts:{impersonationLevel=impersonate}!\\COMPUTERNAME\ROOT\MicrosoftExchangeV2").InstancesOf("Excha nge_Mailbox") get-mailboxstatistics –server $servername For Each objExchange_Mailbox in listExchange_Mailboxs WScript.echo "AssocContentCount =” + objExchange_Mailbox.AssocContentCount WScript.echo " DateDiscoveredAbsentInDS =” + objExchange_Mailbox.DateDiscoveredAbsentInDS WScript.echo " DeletedMessageSizeExtended =" + objExchange_Mailbox.DeletedMessageSizeExtended WScript.echo " LastLoggedOnUserAccount =" + objExchange_Mailbox.LastLoggedOnUserAccount WScript.echo " LastLogoffTime =" + objExchange_Mailbox.LastLogoffTime WScript.echo " LastLogonTime =" + objExchange_Mailbox.LastLogonTime WScript.echo " LegacyDN =" + objExchange_Mailbox.LegacyDN WScript.echo " MailboxDisplayName =” + objExchange_Mailbox. MailboxDisplayName WScript.echo " MailboxGUID =" + objExchange_Mailbox.MailboxGUID WScript.echo " ServerName =" + objExchange_Mailbox.ServerName WScript.echo " Size =" + objExchange_Mailbox.Size WScript.echo " StorageGroupName =" + objExchange_Mailbox.StorageGroupName WScript.echo " StorageLimitInfo =" + objExchange_Mailbox.StorageLimitInfo WScript.echo " StoreName =" + objExchange_Mailbox.StoreName WScript.echo " TotalItems =" + objExchange_Mailbox.TotalItems Next データ ベース 管理 Dim StorGroup as New CDOEXM.StorageGroup StorGroup.DataSource.Open "LDAP://" + DCServer + "/ CN=First Storage Group,CN=InformationStore,CN=" + Server + ",CN=Servers,CN=First Administrative Group, CN=Administrative Groups,CN=First Organization, CN=Microsoft Exchange,CN=Services, CN=Configuration," + DomainName StorGroup.MoveLogFiles("C:\newlogPath", 0) 受信者 管理 Dim objMailbox As CDOEXM.IMailboxStore Set objMailbox = GetObject("LDAP://" + DCServer + "CN=FOO,CN=users," + DomainName) objMailbox.CreateMailbox "LDAP://" + DCServer + "/CN=Private MDB,CN=First Storage Group,CN=InformationStore,CN=" + Server + ",CN=Servers,CN=First Administrative Group, CN=Administrative Groups,CN=First Organization, CN=Microsoft Exchange,CN=Services, CN=Configuration," + DomainName move-storagegrouppath -identity "First Storage Group" –log "C:\newlogPath" enable-mailbox -identity domain\FOO –database "First Storage Group\Private MDB" 71 WBEM - Web Based Enterprise Management http://www.dmtf.org/standards/wbem マイクロソフトやインテル、シスコシステムズ、旧コンパック・コンピュータなどによって提案され、標準化 団体DMTF(Desktop Management Task Force)によって標準化された規格である。その名の通り、「Web ベー スのエンタープライズ管理」のための仕様であり、ネットワーク上に存在するサーバーや OS、ネットワーク 機器などの統合管理に必要なプロトコルやデータ構造を規定する。要するに、従来の SNMP(Simple Network Management Protocol)や syslog に代わる、HTTP と XML をベースとした新世代のネットワーク管理プロトコ ルである。すでにマイクロソフト Windows や HP-UX などのおもなOSをはじめ、サーバー製品、ストレージ製 品、ネットワーク機器、そしてHP OpenView をはじめとするネットワーク管理ツールにおいて、業界標準の ネットワーク管理プロトコルとしてサポートされている。 出典 http://h50146.www5.hp.com/products/software/oe/hpux/developer/column/smh_02/ 72 HP における WBEM の実装 出典 http://h50146.www5.hp.com/products/software/oe/hpux/developer/column/smh_02/ 73 Solaris における WBEM の実装 出典 http://docs.oracle.com/cd/E19455-01/8067119/6jg10nqef/index.html 74 Microsoft の 実装 75 History of Microsoft Management Framework 2000年 Windows 2000 に WMI をインプリメント – 29 WMI プロバイダを含む – 同時に Windows NT, 98, 95 用の WMI もダウンロード開始 (15 WMI プロバイダー) ※どちらかといえば ”プロバイダー” 提供ベンダー向けのテクノロジー ※ Windows ファミリ間の相互運用性に留まる WS-Management とは Web Services for Management のこと。Windows Server ではない。 2005年 WS-Management が DMTF へ提出、承認 2007年 Windows Server 2008 に WS-Management を実装(WinRM) • HTTP/S を介して他プラットフォームとの接続が可能に • Windows PowerShell で WinRM を介したリモートサーバー管理が標準手法 として取り込まれる 76 Windows Management Framework http://www.microsoft.com/downloads/ OS WMF 3.0 WMF 4.0 Windows 7 SP1 以降 SP1 以降 Windows Server 2008 SP2 以降 × Windows Server 2008 R2 SP1 以降 SP1 以降 Windows 8 標準 ○ Windows 8.1 ー 標準 Windows Server 2012 標準 ○ Windows Server 2012 R2 ー 標準 前提条件 • Windows PowerShell ISE がインストールされていること • Microsoft .NET Framework 4.0 がインストールされていること 77 Windows Management Framework IT Pro IT Developer Solution Developer Service Provider Windows Management Framework 開 発 誰が作るの? 標準化されたアクセス Windows PowerShell 標準化されたプロトコル WS-Management(WinRM) (Web Service for Management) 標準化された CIMOM、SMI-S オブジェクトモデル CPU 他の プラットフォーム http WS-Man CIMOM、 SMI-S Storage Network Devices SMI-S(Storage Management Initiative - Specification) 78 The Open Group Membership 2012/10/5 時点 Platinum - 5 • Capgemini Netherlands • Hewlett-Packard USA • IBM USA • Kingdee Software (China) Co. Ltd China • Oracle Corporation USA Gold – 44(抜粋) • Microsoft Corporation USA • NTT Data Corporation • ReGIS Inc. Silver – 256 (Japan のみ抜粋) • Asahi Techneion Co., Ltd • AXE, Inc. • eflow Inc. • Information-technology Promotion Agency, Japan • Japan Aerospace Exploration Agency (JAXA) • Mizuho Information and Research Institute, Inc. • Nissan Motor Co., Ltd. • Nomura Research Institute, Ltd. • Rococo Co Ltd • SIOS Technology, Inc. • Sony CSL • Symphony Ltd. Academic – 38 (Japan のみ抜粋) • Aoyama Gakuin University • Kyoto University • Nagoya University • The University of Tokyo Information Technology Center 79 Open Management Infrastructure(nanoWBEM) • オープンソース版 CIM Server • 軽量 250KB、C で開発されている Windows PowerShell、その他 WinRM Client WinRM Server WS-Management(WinRM) Providers : CIMOM,SMI-S CPU Storage Network Devices 各種言語 OMI Client OMI Server WS-Management(OMI) Providers : CIMOM,SMI-S CPU Storage Network Devices 80 81 OMI サポート プラットフォーム • HP-UX 11i v2 and v3 (PA-RISC and IA64) • Sun Solaris 8 and 9 (SPARC) and Solaris 10 (SPARC and x86) • Red Hat Enterprise Linux 4 (x86/x64) and 5 (x86/x64) Server • Novell SUSE Linux Enterprise Server 9 (x86) and 10 SP1 (x86/x64) • IBM AIX v5.3 and v6.1 (POWER) • MacOS 10.5 (Intel) • Windows(限定的) 最新版は OMI Source - v.1.0.7a (2013年5月) 82 http://www.opengroup.org/ 83 マイクロソフト製品と Windows PowerShell の関係 • 製品ごとに専用の”コマンドレット”が用意されている • 多くの管理 GUI は裏でコマンドレットを呼んでいる • インフラ担当者に、各製品への”標準化されたアクセス方法”を提供する Active Directory 管理センター PowerShell コンソール System Center Virtual Machine Manager Active Directory PowerShell Module Hyper-V PowerShell Module Active Directory Hyper-V 84 Windows PowerShell ISE • Powershell_ise.exe • Windows PowerShell 専用エディタ • IntelliSense に対応 スクリプトエディタ スクリプト実行画面 コマンドレットを直接実行 英語圏の人たちは”アイス” と読むらしい コ マ ン ド レ ッ ト 検 索 85 基礎編 2. 基本的なコマンドレットと書式の基礎 86 事前準備 • コンソールの環境設定 • 簡易編集を有効に • エクスプローラー(フォルダー)の環境設定 • 「拡張子を表示しない」を無効に • 実行ポリシーの設定 ※オンプレミスの”署名無しスクリプト”を実行できるようにする PS C:\>Set-ExecutionPolicy RemoteSigned • リモートからの操作を有効にする(リモーティングの有効化) PS C:\>Enable-PSRemoting –force • 必要に応じて自分専用の初期設定ファイルを作成(規定では存在しない) PS C:\>notepad $profile 87 実行ポリシーの設定~ Set-ExecutionPolicy http://technet.microsoft.com/ja-jp/library/dd347628.aspx • • “管理者として実行” する必要がある 実行ポリシー – – – – – “ポリシーの設定”は、規定では Restricted:制限つき (オペレーターモード)(規定値) コンピューター全体に影響する。 • 対話形式のみ 適用範囲を制限するには、 • スクリプトは実行できない Scope も同時に定義する。 AllSigned:署名 • スクリプトは、信頼された発行元による署名が必要 RemoteSigned:リモートの署名 • “インターネットゾーン” のスクリプトは信頼された発行元による署名が必要 Unrestricted:無制限 • すべてのスクリプトを実行可能 • リモートのスクリプトについては常に警告 Bypass:バイパス • 何もブロックされず警告も表示されない 88 コマンドレットの構造 <操作>-<ターゲット> (例) Checkpoint-VM Compare-VM Export-VM Get-VM Import-VM Measure-VM Move-VM New-VM Remove-VM Rename-VM Repair-VM Restart-VM Resume-VM Save-VM Set-VM Start-VM Stop-VM Suspend-VM 89 コマンドレットとモジュール • PowerShell の実行単位は「コマンドレット」 • コマンドレットはモジュール(Module)によって提供される • モジュールが読み込まれていないとコマンドレットを使用することは できない(Import-Module <モジュール名>) CmdLet CmdLet CmdLet CmdLet Module 構造 Add-Computer Add-Content Checkpoint-Computer Clear-Content Clear-EventLog Clear-Item Clear-ItemProperty Complete-Transaction Microsoft.PowerShell. Management 規定のモジュール Add-VMDvdDrive Add-VMFibreChannelHba Add-VMHardDiskDrive Add-VMMigrationNetwork Add-VMNetworkAdapter Add-VMNetworkAdapterAcl ・ ・ ・ Hyper-V 例 90 モジュールに関するコマンドレット • 読み込まれているモジュール一覧の取得 PS C:\> Get-Module • 使用可能なモジュール一覧の取得 PS C:\> Get-Module -ListAvailable • モジュールを読み込む PS C:\> Import-Module <モジュール名> PS C:\> Import-Module Hyper-V • 使用可能なモジュールを全て読み込む PS C:\> Import-Module (Get-Module -ListAvailable).Name 91 コマンドレット情報を取得する • 使用可能なコマンドレット一覧を取得する PS C:\> Get-Command • “-VM” という文字列を含むコマンドレットの一覧 PS C:\> Get-Command *-vm* -CommandType Cmdlet • 特定のモジュール内のコマンドレット一覧 PS C:\> Get-Command -Module Hyper-V • コマンドレットの書式 PS C:\> Get-Help <コマンドレット> -detailed PS C:\> Get-Help Move-VM -detailed 92 エイリアス コマンドレットにはエイリアスが用意されているものがある • 入力の簡易化 • DOSコマンドやLinux系シェルとの互換性 • エイリアスの一覧を取得する PS C:\> Get-Alias 93 コマンドレットの戻り値 • コマンドレットの戻り値は“オブジェクト”である • PowerShell はオブジェクトを操作する言語 • 戻り値を「どのように操作できるか」を知っていることが重要 • オブジェクトには「メソッド」と「プロパティ」が用意されている 戻り値を直接、”操作”することが可能 Get-Service サービス一覧 stop() オブジェクト 94 もしも”オブジェクト”が自転車だったら... プロパティ メソッド 操作 プロパティ 色 メソッド ペダルをこいで前に進む サイズ ハンドルを右に切る 型 ハンドルを左に切る ブランド フロント ブレーキをかける パーツ リア ブレーキをかける 95 もしも”オブジェクト”が「Windows のサービス」だったら。。。 プロパティ メソッド DisplayName Stop() MachineName Start() Status DependentServices Windows サービス Pause() 96 メソッドとプロパティを調べるには • コマンドレットのメソッドとプロパティを表示 <コマンドレット> | get-member <コマンドレット> | get-member | sort-object Name | format-list ※ COMのメンバーも取得できる New-Object -com scripting.filesystemobject | Get-Member • サービスに対して行える操作を取得する Get-Service | Get-Member • 仮想マシンに対して行える操作を取得する Get-VM | Get-Member 97 TIPS オブジェクトであるということは... PS C:\>$a = “abc” #普通ならば $a は”文字列” になるけれど... #オブジェクトだからメソッドとプロパティが用意されている PS C:\>$a.ToUpper() PS C:\>ABC PS C:\>$a.ToUpper().Split("B")[0] PS C:\>A 98 コマンドからの出力もオブジェクト化される ipconfig の出力結果からIPアドレスを取りだす PS C:\> (ipconfig)[18].Split(":")[1].Trim() object ipconfig の の18行目 出力結果 (0から数えて) コロンで分割した (0から数えて)2 つ目の値 前後の空白を トリミング IPv4 アドレス . . . . . . . . . . : 192.168.1.100 99 PSドライブ ファイルシステムだけではなく、さまざまなオブジェクトがドライブとしてアク セス可能(CD コマンドで移動可能) PS C:\> Get-PSDrive ファイルシステム エイリアス(Alias:) レジストリ(HKLM:、HKCU:) 証明書(Cert:) 環境変数(Env:) 変数(Variable:) WSMAN設定(Wsman:) Active Directory(AD:) IIS(IIS:) Remote Desktop Service(RDS:) モジュールが読み込まれて いないと使えないドライブ もある (例)ActiveDirectory 100 基礎編 3. 基本的な文法とスクリプトの作り方 さまざまな使用例から使い方を学びましょう 101 1. 2. 3. 4. 5. 6. 7. 8. 起動中のサービス一覧 パイプライン Where-Object による条件指定 特定のサービスを停止する () でオブジェクトを表現する ネットワーク情報を取得する 出力結果のフォーマット変換 ネットワークの設定を変更する ローカルコンピューター名を変更する 変数の宣言 変数の遅延展開 Array 値 ハッシュテーブル 環境変数 リモートからコンピューター名を変更する ※標準コマンドレット or WMI クレデンシャルの使い方 WMI に必要なアクセス権 ドメインに参加させる ※標準コマンドレット or WMI 複数のコンピューターをドメインに参加させる スクリプトの継続行 ファイルの入出力方法 ファイルのコード変換 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. CSV のヘッダー行について 繰り返し処理 イベントログを収集する Select-Object により必要な要素のみを取り出す イベントログをバックアップする 独自のイベントログを登録する 仮想マシンを作成して起動する スクリプトの引数を定義する 名前付き引数 Hyper-V ライブマイグレーションを実行する パフォーマンスログを取得する 役割と機能をインストールする 仮想ドメインコントローラを複製する Hyper-V 仮想スイッチを作成する リモートコンピューターから機能を一括で削除する リモートコンピューターを一括でシャットダウンする すべての Hyper-V ホストの仮想マシンを強制的にシャッ トダウンする すべてのHyper-V ホストのライブマイグレーションを有効 化する 102 1.起動中のサービス一覧を取得する object サービス一覧 パイプ PS C:\>get-service | where-object {$_.Status -eq "Running"} サービス一覧 を出力 object まオ まブ 渡ジ さェ れク るト の サービス一覧 103 パイプラインについて コマンドレット1 コマンドレット2 結果 結果 オブジェクト 入力パラメタ コマンドレット3 入力パラメタ PS > Get-Service | Where-Object {$_.Status -EQ "Running"} | Select-Object -Property Name, Servicetype | Sort-Object -Property ServiceType PS > Get-Service | Where-Object Status -EQ "Running" | Select-Object Name, Servicetype | Sort-Object ServiceType V3ではこう書ける • • • • サービスの一覧を取得 Status が Running のみを抽出 Name プロパティとServiceType プロパティを抽出 ServiceType でソート 104 TIPS 条件を指定して結果を絞り込む Where-Object #サイズが1024バイト以上のファイルを検索する Dir | Where-Object {$_.length -GT 1024} ` |Select-Object Name,length #Active Directory のユーザー名に”a”を含むユーザーを取得する Get-ADUser -Filter * ` |Where-Object {$_.name -Like “*a*”} ` | ForEach-Object name 105 TIPS PS 3.0 では書式を簡略化できます PS C:\>get-service | where-object {$_.Status -eq "Running"} V3 ではこう書ける PS C:\>get-service | where-object Status -eq "Running" 106 2.特定のサービスを停止する PS C:\>Stop-Service WSerarch メソッド PS C:\>(Get-Service -Name WSearch).Stop() Windows Search サービスの インスタンスを取得 インスタンスに対して メソッドを実行 object Windows Search 107 TIPS()で括るとオブジェクトを表す #Dir の出力結果の最初の行から #Nameプロパティだけを取り出す (dir)[0].Name #変数を使用すると以下のように書き換えられる $D = Dir $D[0].Name 108 3.ネットワーク情報を取得する ネットワークアダプタの一覧 Format-List の略 PS C:\> Get-NetAdapter | FL Name, InterfaceIndex, MacAddress IP アドレスの取得 PS C:\> Get-NetIPAddress -InterfaceIndex 28 -AddressFamily IPv4 109 TIPS 出力結果のフォーマットを変換 dir | format-table Name,Length dir | format-list Name,Length dir | format-wide Name -column 6 dir | out-gridview 110 4.ネットワークの設定を変更する 静的なIPV4アドレスを設定する PS C:\>New-NetIPAddress -InterfaceIndex 24 -IPAddress 192.168.205.102 -AddressFamily IPv4 -PrefixLength 24 -DefaultGateway 192.168.205.254 既存の静的アドレスを変更する場合には Set-NetIPAddress を使用する DNS の設定 PS C:\>Set-DnsClientServerAddress -Interface 24 -ServerAddress 192.168.205.1, 192.168.205.3 IP アドレスの削除 PS C:\> Remove-IPAddress -InterfaceIndex 24 -AddressFamily IPv4 DNSの設定を削除する PS C:\> Set-DnsClientServerAddress -Interface 24 -ResetServerAddress DHCP を有効にする PS C:\> Set-NetIPInterface -InterfaceIndex 24 -Dhcp Enabled 111 5.ローカルコンピューター名を変更する ローカルコンピューター名の取得 方法1 PS C:\> $Env:ComputerName 方法2 PS C:\> (Get-WmiObject -Class Win32_ComputerSystem).Name ローカルコンピューター名の変更 標準のコマンドレットを使用する場合 C:\> Rename-Computer -NewName “tfwin8-xx” -Force -Restart WMI を使用する場合 PS C:\> $New_ClientName = “New_ClientName” PS C:\> $SysInfo = Get-WmiObject -Class Win32_ComputerSystem PS C:\> $SysInfo.Rename($New_ClientName) PS C:\> Restart-Computer 112 TIPS 変数を使うには $FirstName = "Junichi" $LastName = "Anno" $FullName = $FirstName + " " + $LastName Write-Output $FullName $arrFullName = $FullName.Split(" ") Write-Output $arrFullname[0] PS C:\> C:\hogehoge.ps1 Junichi Anno Junichi 出力結果 113 TIPS 変数の宣言について 通常は自動判別 PS > $A = 1 PS > $B = “1” PS > $A + $B 2 PS > $B + $A 11 PS > $A = “abc” PS > $A + $B abc1 System.Int32 System.String 先にある System.Int32 に自動変換 自動変換できない値で あればエラーとなる 先にあるSystem.String に自動変換 System.String で置き換えが可能 114 明示的に宣言することも可能 PS > [System.Int32] $A = 1 PS > [System.String] $B = “abc” PS > [System.Array] $C = “今年は”, 2012, “年です” 0: 今年は 1: 2012 2: 年です [System.String] [System.Int32] [System.String] PS > $A = 987.654 PS > $A Int32 にキャストされる 988 明に宣言すると自動変換はできない PS > $A = “Hello” Cannot convert value "Hello" to type "System.Int32“ PS > [System.String] $A = “Hello” 115 変数を削除する PS > [System.Int32] $A = 1 PS > Remove-Variable A 自分で作成した変数を全て削除 ※削除できないものについてエラーが出る PS > Get-Variable | Remove-Variable 116 TIPS 変数の展開について PS >$FirstName = "Junichi" PS >$LastName = "Anno" PS >$FullName = “$FirstName $LastName” PS >Write-Output $FullName Junichi Anno PS >$FullName = ‘$FirstName $LastName’ PS >Write-Output $FullName $FirstName $LastName ダブルクオーテーションで 括った場合は変数は展開さ れる シングルクオーテーション で括った場合には変数は展 開されない 117 TIPS 変数の遅延展開 通常 PS > $Name = “Junichi” PS > $Message = “Hello $Name” PS > $Message Hello Junichi この時点で変数は展開される 遅延展開 PS > $Name = “Junichi” {} で括ると変数は展開されない PS > $Message = { “Hello $Name” } $Message を定義した後で $Name に値を入れているこ PS > $Name = “Taro” とに注意 PS > $Message Hello $Name PS > & $Message Echo の代わりに & を使用 Hello Taro 118 遅延展開を利用して関数として定義 PS > $Message = { Param( $Name ) “Hello $Name” } PS > & $Message Junichi Hello Junichi 119 TIPS Array 値 Array の作り方 空のアレイを作成(あえてしなくてもよい) PS > $Users = @() PS > $Users = “Junichi”, ”Naoko”, “Kazunori” PS > $Users.Count 3 PS > $Users Junichi Naoko Kazunori PS > $Users += “Maki” 値を追加 数値を追加 PS > $Users += 512 {}で括っているので遅延展開変数 PS > $a = { [system.math]::Pow( 2, $N ) } PS > $Users += $a 遅延展開変数を追加 120 Array 値の参照 PS > $Users[3] Maki 配列の一番最後 PS > $Users[-1] PS > $N = 6 遅延展開変数の入った行を参照 PS > & $Users[5] 64 $users から値を取りだし PS > Foreach ($u in $Users) { New-ADUser -Name $u } ながらユーザーを作成 PS > $Users[2..4] 配列の2番から4番を取りだす kazunori と一致するものがあるかどうかを検査 PS > ($Users -eq “Kazunori”).Count Kazunori 以外のものを抽出 PS > $Users -ne “Kazunori” M が含まれる行を抽出 PS > $Users -like “*M*” 121 PS > $arrINT = 1,2,3,4,5,6,7,8,9 PS > $arrINT -ge 5 2つの配列を合成 PS > $Users += $arrINT 2つの配列を合成 PS > $Users | Sort-Object $_ 昇順に並べ替えて出力 PS > $Users = $Users -ne “Kazunori” Kazunori を削除 PS > [System.Array]::Reverse($Users) Users の中の並び順を逆にする 122 空白を文字列で埋める(PadLeft / PadRight) ## $N[] に、001 ~ 100 の文字列を格納する PS > $N = @() PS > 001..100 | % { $N += ("$_").Padleft(3,"0")} PS > User$N 001 002 ・ 100 PS > $VMs = $N | % {echo VM$_} PS > $VMs VM001 VM002 ・ VM100 123 TIPS HashTable HashTable の作り方 PS > $Users = @{} 注意 Array は () PS > $Users.0001 = “Junichi” キー 1 に 値 Junichi を登録 PS > $Users.”0001” = “Junichi” キー 0001 に 値 Junichi を登録 PS > $Users.Add( “0001”, “Junichi” ) PS > $Users.Remove(“0001”) キー 0001 の行を削除 124 CSV ファイルから値を読み込んでHashTable を作成 PS > $USDJPY = Import-CSV -Path C:\tools\USDJPY.csv –Encoding Default PS > $HT = @{} PS > While ( $i -lt $USDJPY.Count ) {$HT.Add( $USDJPY.日付[ $i ], $USDJPY.終値 [ $i ] ) ; $i++ } PS > $HT.”2012/2/10” 77.65 125 TIPS 環境変数の取得 #環境変数の一覧を取得 cd env: dir #特定の環境変数を取得 $env:computername $env:username $env:userdomain $env:SessionName 126 6.コンピューター名を変更する(リモートから) 標準のコマンドレットを使用する ##スタンドアロンのコンピューターの場合 PS C:\> $ClientName = “ClientName” PS C:\> $Cred = Get-Credential PS C:\> $New_ClientName = “New_ClientName” PS C:\> Rename-Computer -ComputerName $ClientName -LocalCredential $Cred -NewName $New_ClientName -Force -Restart ##ドメインに参加しているコンピューターの場合 PS C:\> $ClientName = “ClientName” PS C:\> $Cred = Get-Credential PS C:\> $New_ClientName = “New_ClientName” PS C:\> Rename-Computer -ComputerName $ClientName -DomainCredential $Cred -NewName $New_ClientName -Force -Restart 127 WMI を使用する 変更 WMI Server Client PS C:\> $ClientName = “ClientName” PS C:\> $Cred = Get-Credential PS C:\> $New_ClientName = “New_ClientName” PS C:\> $SysInfo = Get-WmiObject -Class Win32_ComputerSystem -ComputerName $ClientName -Credential $Cred PS C:\> $SysInfo.Rename($New_ClientName) PS C:\> Restart-Computer -ComputerName $ClientName -Credential $cred -Force 128 TIPS クレデンシャルの作成 その1 PS C:\> $Cred = Get-Credential ポップアップが表示される その2 PS C:\> $user = “administrator “ PS C:\> $pass = ConvertTo-SecureString "P@ssw0rd“ -AsPlainText -Force PS C:\> $Cred = New-Object System.Management.Automation.PSCredential $user, $pass 129 TIPS WMI Tester http://technet.microsoft.com/en-us/library/cc782719(v=ws.10) • WMI への接続性をテストするツール • リモートコンピューターへの接続も テストできる 130 TIPS 非ドメインメンバーから WMI接続 が拒否される原因と対処 代表的なエラー番号 • 0x800706ba • 0x80041003 • 0x80070005 代表的な原因 • Firewall の設定 • アクセス権 131 必要なアクセス権 • Distributed COM Users メンバーである こと • (規定では)システム管理者であること ※wmimgmt.msc で変更可能 132 必要な Firewall の設定 • Windows Management Instrumentation のルール 133 7.ドメインに参加させる Server 参加指示 AD Domain Client Client Client Workgroup 標準のコマンドレットを使用する PS C:\> $Domain = “tf.com” PS C:\> $Client = “ClientComputer” PS C:\> $LocalCred = Get-Credential junichia PS C:\> $DomainCred = Get-Credential tf\administrator PS C:\> $Admin = “tf\administrator” PS C:\> $Pass = “P@ssword” PS C:\> Add-Computer -ComputerName $Clienit -LocalCredential $Cred -Credential $DomainCred -DomainName $Domain -OUPath “OU=営業部” -Restart -Force 134 WMIのクラスを直接使用する 認証に関する通信を暗号化する PS C:\> $Domain = “tf.com” これを指定しないと以下のエラー PS C:\> $Client = “ClientComputer” “Client connection to WINMGMT needs to be encrypted for this PS C:\> $Cred = Get-Credential junichia operation. Please adjust your PS C:\> $Admin = “tf\administrator” IWbemServices proxy security settings and retry. ” PS C:\> $Pass = “P@ssword” PS C:\> $SysInfo = Get-WmiObject -Class Win32_ComputerSystem -ComputerName $ClientComputer -Credential $Cred -Authentication PacketPrivacy PS C:\> $SysInfo.JoinDomainOrWorkgroup($Domain, $Pass, $Admin, “OU=xx”, 3 ) PS C:\> Restart-Computer -ComputerName $Client -Credential $Cred -Force 1: ドメインに参加 + 2: コンピューターアカウントの作成 135 8.複数のコンピューターをドメインに参加させる 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 # 各種定数の設定 Client Client CSV Server $Cred = Get-Credential junichia $Domain = "tf.com" $Admin = "tf\administrator" tfwin8-01,192.168.205.101,経理部 $Pass = "P@ssword" tfwin8-02,192.168.205.102,営業部 # いったん、SJISで作成したファイルを読み込み、UNICODEで保存する ・ $InputFile = "C:\Tools\Computers.csv" ・ $OutputFile = "C:\Tools\Computers_unicode.csv" Get-Content $InputFile -Encoding String | Out-File $OutputFile -Encoding unicode # CSVファイルを読み込む $Computers = Import-Csv -Path $OutputFile -Header ComputerName,IPAddress,Department -Delimiter "," # コンピューター名と部署を取り出し、ドメインに参加させる ForEach ($c in $Computers) { $Client = $c.ComputerName $OU = "OU=" + $c.Department + ",DC=TF,DC=COM $SysInfo = Get-WmiObject -Class Win32_ComputerSystem -ComputerName $Client ` -Credential $Cred -Authentication PacketPrivacy $SysInfo.JoinDomainOrWorkgroup($Domain, $Pass, $Admin, $OU , 3 ) Restart-Computer -ComputerName $Client -Credential $Cred -Force } 136 TIPS 行継続 アクサン グラーブ記号 (`) を使用する copy-item C:\tmp\*.txt ` -destination C:\ こ い つ 137 TIPS 入出力方法 これを抑えておけば、ひとまずたいていのことはできます #標準出力 Write-Output “Hello” #ファイルから入力 Echo “Hello” $file = Get-Content -Path c:\tmp\list.txt $file = type c:\tmp\list.txt #標準入力 $InputData = Read-Host #CSVファイルから入力 $file = Import-CSV -Path c:\test.csv #ファイルに出力 Out-File -filepath C:\tmp\list.txt -inputobject $Record 138 TIPS 出力方法の違い 空白で区切られる PS C:\> 1 + 2 + 3 6 PS C:\> “1” + “2” + “3” 123 PS C:\> Windows PowerShell <エラー> ※ Echo は Write-Output のAlias PS C:\> Write-Output 1 + 2 + 3 1 + 2 + 3 PS C:\> Echo Windows PowerShell Windows PowerShell PS C:\> Echo “Windows PowerShell” Windows PowerShell 139 TIPS ファイルのコード変換 SJIS作成したファイルは日本語が正しく扱われないことがある ∴ Get-Content で読み込み、Out-File でUnicodeで保存する Get-Content -Path $Input -Encoding String | ` Out-File -Encoding UNICODE 指定可能な文字コード String Unicode Byte BigEndianUnicode UTF8 UTF7 UTF32 Ascii Default Oem 140 TIPS Import-CSV でのヘッダーの取り扱いについて • 規定では、1行目はヘッダーとして扱われる ComputerName, IPAddress, Department tfwin8-01,192.168.205.101,経理部 tfwin8-02,192.168.205.102,営業部 ・ ・ • ヘッダーが無い場合には -Header パラメタで指定可能 • -Header を指定すると1行目はデータとして扱われる • ヘッダー単位(列単位)で取り出しが可能 $Computers = Import-Csv -Path $OutputFile -Header ComputerName,IPAddress $Computers.IPAddress 141 TIPS Out-GridView を使用して出力結果をながめる 入力したグリッド形式データを参照するための EXCEL VIEWER 的ツール Import-CSV -Path $File | Out-GridView 142 TIPS 繰り返し処理1 Active Directory ユーザー一覧から name プロパティをリストする #ForEach-Object Get-ADUser -Filter * | ForEach-Object {$_.name} Get-ADUser -Filter * | ForEach-Object name V3 #foreach $Users = Get-ADUser -Filter * foreach ($user in $Users) { $user.name } 143 TIPS 繰り返し処理2 #1から10までを出力 1..10 #1から10 をリダイレクトして出力 1..10 | % {echo $_ } #User1 から User10 を作成 1..10 | % {New-ADUser “User$_” } ※ % は foreach のエイリアス 144 TIPS 繰り返し処理3 $i = 0 do { } Write-Host $i $i++ while ($i -lt 10) $i = 0 do { } Write-Host $i $i++ until ($i -ge 10) 145 9.イベントログを収集する リモートコンピューターのセキュリティログから、最新10個のログを取りだす C:\> Get-EventLog -LogName Security -ComputerName tfdc01 -Newest 10 特定の日時範囲のログを取りだす C:\> Get-EventLog -LogName Security -ComputerName tfdc01 -After “2012/6/1 00:00:00” -Before “2012/6/1 00:10:00” 特定のイベントIDを取りだす C:\> Get-EventLog -LogName Security -ComputerName tfdc01 -InstanceID 4632 失敗した監査を取りだす C:\> Get-EventLog -LogName Security -ComputerName tfdc01 -EntryType FailureAudit メッセージに “ログオン” という言葉が含まれているログを取りだす C:\> Get-EventLog -LogName Security -ComputerName tfdc01 -Message “*ログオン*” 146 イベントログを集計する C:\> Get-EventLog -LogName Application | Group-Object -Property EntryType -NoElement C:\> Get-EventLog -LogName Application |Group-Object -Property Source,EntryType -NoElement | Select-Object Name,Count 147 TIPS Select-Object で必要な要素のみを取りだす 結果から必要な要素だけを抜き出して処理する パイプの後ろで使用することをお勧め(なんかおかしい...) PS C:\> $Data = Dir × PS C:\> Select-Object -InputObject $Data -Property Name ○ PS C:\> $Data | Select-Object -Property Name 重複データを除く $data |Select-Object -Unique -Property Name 最後の10個だけ取得 $data | Select-Object -Last 10 最初の5個だけ取得 $data | Select-Object -First 5 148 10. イベントログをバックアップする PowerShell は管理者モードで起動してください セキュリティイベントログをローカルにバックアップする(EVT形式) C:\> $logFileName = "Security" C:\> $exportFileName = "C:\tmp\" + $logFileName + (get-date -f yyyyMMddhhmmss) + ".evt" C:\> $exportfilename C:\> $logFile = Get-WmiObject Win32_NTEventlogFile | Where-Object {$_.logfilename -eq $logFileName} C:\> $logFile.backupeventlog($exportFileName) 149 11.独自のイベントログを登録する ログファイル名 TechFielders、イベントソース TechFielders を新規に登録する C:\> New-EventLog -Source "TechFielders" -LogName "TechFielders" TechFielders ログにイベントログを書き込む C:\> Write-EventLog -LogName TechFielders -Source “TechFielders” -EntryType Information -EventId 5963 -Message “元気出せこの野郎!1,2,3 ダァ!" 150 12. 仮想マシンを作成して起動する PS C:\> .\CreateVirtualMachine.ps1 -VMName “VM01" -Mem 1024mb CreateVirtualMachine.ps1 1 param([string] $VMName = "NA", [int] $CPU = 1, [int] $Mem = 10MB) 2 echo -InputObject $VMName, $CPU, $Mem 3 $SwitchName = "Intel(R) 82579LM Gigabit Network Connection - Virtual Switch" 4 New-VM -BootDevice CD ` 5 -MemoryStartupBytes $Mem ` 6 -Name $VMName ` 7 -SwitchName $SwitchName ` 8 -VHDPath \\junichia-vdi\$VMName\$VMName.vhdx 9 Set-VM -ProcessorCount $CPU -DynamicMemory -Name $VMName 10 Add-VMNetworkAdapter -VMName $VMName -SwitchName $SwitchName 11 Start-VM -Name $VMName 151 TIPS 引数を受け取る 5つの引数 C:\> .\hogehoge.ps1 My name is “Junichi Anno” . Write-Output $args[3] Junichi Anno foreach ( $a in $args ) { Write-Output $a } My name is Junichi Anno . 152 TIPS 名前付き引数の使い方 引数を所定の名前の変数に格納することで、文法チェック等が行いやすくなる C:\> hogehoge.ps1 -userid anno param([string] $UserID = “ID", [string] $Password =“PASS") Write-Output $userid Write-Output $Password 規定値 anno PASS 出力結果 153 13. Hyper-V ライブマイグレーション メモリ内データ Guest Host01 構成情報 Guest Host01 \\Server\Share\xxx.vhdx $Source の中の VM で始ま るゲストOSを検索している $Source = “HostSV01” $Dist = “HostSV02” $VMs = get-vm -ComputerName $Source -Name VM* foreach ($VMName in $VMs.Name) { Move-VM -ComputerName $Source -Name $VMName -DestinationHost $Dist } 154 14. パフォーマンスログを取得する プロセッサー(コア単位)の利用率を1秒に1回取得して表示する 1 2 3 4 5 6 7 8 9 10 11 Do { $perf =Get-WmiObject -Class win32_perfformatteddata_perfos_processor ` -Property PercentProcessorTime 目的のパフォーマンスカウン foreach ($p in $perf ) { タ(今回はCPU使用率)が含ま $outrec = "Processor" + $i + ":" + $p.PercentProcessorTime れているWMIクラスを指定する echo $outrec } 1秒スリープ Start-Sleep -Seconds 1 cls 画面をクリア } while (-1) 155 TIPS パフォーマンスカウンターの調査方法 パフォーマンスカウンタークラスの一覧を取得するには C:\> Get-CimClass Win32_PerfFormatted* |ft CimClassName C:\> Get-CimClass Win32_PerfRaw* |ft CimClassName win32_perfformatteddata_perfos_processor クラスが持ってい るカウンターの一覧を取得する C:\> $PerfMon = Get-CimClass Win32_PerfFormattedData_perfos_processor C:\> $PerfMon.CimClassProperties |ft Name 156 15. 役割と機能をインストールする 役割/機能の一覧を取得する C:\> Get-WindowsFeature C:\> Get-WindowsFeature |Select-Object Name 157 ServerCore にすべての GUI をインストールする(フルインストール) PS C:\> Add-WindowsFeature -Name User-Interfaces-Infra -IncludeAllSubFeature -IncludeManagementTools ServerCore に管理ツールだけをインストールする(MinShell) PS C:\> Add-WindowsFeature –Name Server-gui-mgmt-infra -IncludeManagementTools 158 (参考)Windows Server 2012 GUI オプション Server Core MinShell Server W/GUI Desktop Experience コマンドプロンプト Available Available Available Available Windows PowerShell サーバーマネージャー Available Available Available Available Not Available Available Available Available MMC コントロールパネル Not Available Available Available Available Not Available Not Available Available Available コントロールパネル内 のアプレット Not Available Some Available Available Available Windows Explorer タスクバー Not Available Not Available Available Available Not Available Not Available Available Available 通知エリア Not Available Not Available Available Available Internet Explorer ヘルプ Not Available Not Available Available Available Not Available Not Available Available Available テーマ Not Available Not Available Not Available Available スタートスクリーン Not Available Not Available Not Available Available WinRTアプリ Not Available Not Available Not Available Available メディアプレーヤー Not Available Not Available Not Available Available 159 ServerManager モジュールでサポートされている コマンドレット PS C:\> Import-Module ServerManager PS C:\> Get-Command -Module ServerManager Alias Alias Function Function Cmdlet Cmdlet Cmdlet Add-WindowsFeature Remove-WindowsFeature Disable-ServerManagerStandardUserRemoting Enable-ServerManagerStandardUserRemoting Get-WindowsFeature Install-WindowsFeature Uninstall-WindowsFeature servermanager servermanager servermanager servermanager servermanager servermanager servermanager 160 16. DC を複製する Windows Server 2012 以降では、仮想化されたドメインコントローラーを複製して 展開することがでる。 (条件) • 複製元はPDCエミュレーターであってはならない • 複製元は Clonable Domain Controllers グループのメンバーでなくてはならない • Hyper-V ホストは Windows Server 2012 • DCは Windows Server 2012 DC01 (pdc) DC02 Hyper-V ホスト Hyper-V ホスト Export VHD Import DC03 Hyper-V ホスト 161 $SourceDC = "DC02" $DistDC = "DC03" $distPDCEmu = DC01" $HyperVHost = “ITCAMP-TMP" PDCエミュレーターを複製元となるDC以外に移動 Move-ADDirectoryServerOperationMasterRole -Identity $distPDCEmu -OperationMasterRole PDCEmulator Get-ADComputer $SourceDC | %{Add-ADGroupMember -Identity "Cloneable Domain Controllers" -Members $_.samAccountName} 複製元DCをClonable Domain Controllers グループのメンバーにする Invoke-Command -ComputerName $SourceDC -ScriptBlock { Get-ADDCCloningExcludedApplicationList -GenerateXml -Force } $SB = "New-ADDCCloneConfigFile -Static ` 新しいドメインコンローラーの -IPv4Address ""192.168.210.51"" ` 構成ファイルを作成 -IPv4DNSResolver ""192.168.210.50"" ` -IPv4SubnetMask ""255.255.255.0"" ` -IPv4DefaultGateway ""192.168.210.254"" ` -CloneComputerName " + $DistDC + ` " -SiteName ""Default-First-Site-Name""" Invoke-Command -ComputerName $SourceDC -ScriptBlock { $SB } Stop-VM $SourceDC 複製元DCをシャットダウン 162 つづき Get-VM $SourceDC | %{ Export-VM $_ -Path C:\VMs} Start-VM -Name $SourceDC 複製元DCをエクスポート 複製元DCを起動 エクスポートした仮想マシンをインポート $CFG = (Dir “C:\VMs\$SourceDC\Virtual Machines\*.xml”).FullName md E:\$DistDC Import-VM -Path "$CFG" -ComputerName $HyperVHost -GenerateNewId -Copy -VhdDestinationPath E:\$DistDC VMの名前が複製元と同じになってしまうので、変更する。ここでは同じHyper-Vホストを使用して いるので、OffになっているほうのDCを変名している。 Get-VM $SourceDC |Where-Object {$_.State -EQ "Off"} | Rename-VM -NewName $DistDC 複製先を起動。起動後自動的にDC間複製が始まる。 Start-VM $DistDC 163 17. 仮想スイッチを作成する $PCName = "itcamp-pc01" Invoke-Command -ComputerName $PCName -ScriptBlock {New-VMSwitch -Name "External" ` -AllowManagementOS $True -NetAdapterInterfaceDescription "Intel(R) 82579LM Gigabit Network Connection"} New-VMSwitch -ComputerName $PCName -Name "WS2012Labs-Public" -SwitchType Private New-VMSwitch -ComputerName $PCName -Name "WS2012Labs-CorpNet" -SwitchType Private New-VMSwitch -ComputerName $PCName -Name "WS2012Labs-Storage" -SwitchType Private New-VMSwitch -ComputerName $PCName -Name "WS2012Labs-Internet" -SwitchType Private New-VMSwitch -ComputerName $PCName -Name "WS2012Labs-HA" -SwitchType Private 164 18. リモートコンピューターから機能を一括で削除する ワークフローを使用してリモートコンピューターからフェールオーバークラス タリングを削除する Workflow RemoveFOCsWF { $PCs = Import-Csv -Path pclist.txt -Header "PC","IP" itcamp-pc01,192.168.210.1 itcamp-pc02,192.168.210.2 itcamp-pc03,192.168.210.3 itcamp-pc04,192.168.210.4 itcamp-pc05,192.168.210.5 itcamp-pc06,192.168.210.6 ・ ・ foreach -Parallel ($pc in $PCs) { Write-Output -InputObject $pc.pc Remove-WindowsFeature -ComputerName $pc.pc Failover-Clustering -IncludeManagementTools Restart } } RemoveFOCsWF 165 19. リモートコンピューターを一括でシャットダウンする Workflow RestartAllPCsWF { $PCs = Import-Csv -Path pclist.txt -Header "PC","IP" foreach -Parallel ($pc in $PCs) { Write-Output -InputObject $pc.pc ##Restart-Computer -PSComputerName $pc.PC -Force Stop-Computer -PSComputerName $pc.PC -Force } itcamp-pc01,192.168.210.1 itcamp-pc02,192.168.210.2 itcamp-pc03,192.168.210.3 itcamp-pc04,192.168.210.4 itcamp-pc05,192.168.210.5 itcamp-pc06,192.168.210.6 ・ ・ } RestartAllPCsWF 166 20. すべての Hyper-V ホストの仮想マシンを強制的にシャットダウン ワークフローを使用して一斉にシャットダウン Workflow StopAllVMs { $PCs = Import-Csv -Path pclist.txt -Header "PC","IP" foreach -Parallel ($pc in $PCs){ ##Get-VM -ComputerName $pc.pc |Start-VM Get-VM -ComputerName $pc.pc |Stop-VM -Force } itcamp-pc01,192.168.210.1 itcamp-pc02,192.168.210.2 itcamp-pc03,192.168.210.3 itcamp-pc04,192.168.210.4 itcamp-pc05,192.168.210.5 itcamp-pc06,192.168.210.6 ・ ・ } 167 21. すべての Hyper-V ホストのマイグレーション設定を有効化 itcamppc01,192.168.210.1 Workflow DisableMigrationWF { itcamppc02,192.168.210.2 $PCs = Import-Csv -Path c:\tools\ps\HOLSetup\pclist.txt -Header "PC","IP" itcamppc03,192.168.210.3 foreach -Parallel ($pc in $PCs) { itcamppc04,192.168.210.4 itcamp##Disable-VMMigration -ComputerName $pc.pc pc05,192.168.210.5 ##Set-VMHost -ComputerName $pc.pc -VirtualMachineMigrationAuthenticationType CredSSP ` itcamp-MaximumVirtualMachineMigrations 2 -UseAnyNetworkForMigration $true pc06,192.168.210.6 ・ Enable-VMMigration -ComputerName $pc.pc ・ Set-VMHost -ComputerName $pc.pc -VirtualMachineMigrationAuthenticationType Kerberos ` -MaximumVirtualMachineMigrations 2 -UseAnyNetworkForMigration $True } } DisableMigrationWF 168 基礎編 5. その他の Tips その他、知っていると便利な使用法について 169 True と False の指定 $True と $False は予約語である C:\> $MyNameIsJunichi = $True C:\> If ($MyNameIsJunichi -eq $True) {Echo 1} 1 170 日時を取得(Date オブジェクト) プロパティ PS C:\> (Date).Year 2012 メソッド PS C:\> (date).adddays(10) 24年 5月 23日 12:49:10 Date Day DayOfWeek DayOfYear Hour Kind Millisecond Minute Month Second Ticks TimeOfDay Year Add AddDays AddHours AddMilliseconds AddMinutes AddMonths AddSeconds AddTicks AddYears CompareTo Equals GetDateTimeFormats GetHashCode GetType GetTypeCode DateTime IsDaylightSavingTime Subtract ToBinary ToFileTime ToFileTimeUtc ToLocalTime ToLongDateString ToLongTimeString ToOADate ToShortDateString ToShortTimeString ToString ToUniversalTime 171 unix のあのコマンドは? ls cp grep sort man clear cat kill tee tail → get-ChildItem → copy-Object → select-String → sort-Object → help → clear-Host → get-Content → stop-Process → tee-Object → get-Content 「アレはあるかな?」と思った ら Get-Alias <unix 上のコマンド> エイリアス tail は登録されてい ないので、自分で登録する必要 がある(後述)。 172 Get-Content で Tail を模してみる ## テキストファイルの5行目から10行目までを表示 (gc .\test.txt)[4..9] ## テキストファイルの最初の5行を表示 gc .\test.txt -totalcount 5 ## テキストファイルの最後の5行を表示 gc .\test.txt | Select-Object -Last 5 ← 時間がかかる可能性があるので –tail をお勧め gc .\test.txt -tail 5 ## 新しく追加された行を待ち合わせて表示 gc .\test.txt -wait -tail 0 ## 新しく追加された行に特定の文字列が含まれていたら表示 gc .\test.txt -wait | Select-String -Pattern ^a 173 tail を Get-Content の Alias として登録する 一時的に使用する(現在のコンソール上でのみ)場合は以下のように入力 Set-Alias tail Get-Content 永続化するには、以下のようにプロファイルに書き込む Add-Content $profile "Set-Alias tail get-content" -Force 174 Part 2 リモーティング編 175 Agenda ~リモーティング編 6. リモーティングの基礎 7. PS セッション • セッションと PS セッション • テンポラリ PS セッション 8. 接続の永続化と再利用可能な PS セッション 9. Windows PowerShell Web Access 176 リモーティング編 6. リモーティングの準備 177 リモーティングを有効にする • 個々の PC で有効にする PS C:\>Enable-PSRemoting –force 処理を受付 Windows Management 要求を透過 WinRM Listener Windows Firewall port 5985 OS 受付窓口 178 Enable-PSRemoting とネットワークプロファイルの関係 ※PowerShell 3.0 の場合 http://technet.microsoft.com/en-us/library/hh849694.aspx ネットワークのプロファイル ドメイン • ADドメインに参加 • DCと通信可能 Windows Server 系 Windows Client 系 WinRM 有効 WinRM 有効 プライベート • • • パブリック DCと通信不可能 ワークグループ 自宅、職場 • • インターネット 公共ネットワーク WinRM 有効 同じサブネットのコン ピューターに対しては WinRM 有効 WinRM 有効 SkipNetworkProfileChec k パラメタを指定して実行 すれば同じサブネットの コンピューターに対して 有効になる パブリックプロファイルの Firewall の制限をすべて取り払うには以下のコマンドで Set-NetFirewallRule -Name “WINRM-HTTP-In-TCP-PUBLIC” -RemoteAddres Any 179 • グループポリシーを使用する WinRM リスナを作成 [コンピューターの構成]-[ポリシー]-[管理用テンプレート]-[Windows コンポーネント] └[Windows リモート管理(WinRM)] 180 WinRM サービスを自動起動にする 181 Windows Firewall で WinRM の要求を受信する [コンピューターの構成]-[ポリシー]-[Windows の設定]-[セキュリティの設定] └[セキュリティが強化されたWindowsファイアウォール] └[セキュリティが強化された Windows ファイアウォール(-------)] └[受信の規則] 182 183 管理できるソースとターゲットを制限する(必要に応じて) 管理用のIPアドレス(ター ゲット側)を指定 管理用のIPアドレス(ソース 側)を指定 184 リモーティングの設定を確認する Listener 名は環境に よって異なります PS C:\> cd WSMan: PS WSMan:\> cd localhost\Listner\Listener_1084132640 PS WSMan:\localhost\Listener\Listener_1084132640> dir WSManConfig: Microsoft.WSMan.Management\WSMan::localhost\Listener\Listener_1084132640 Type ---System.String System.String System.String System.String System.String System.String System.String System.String System.String System.String System.String System.String System.String System.String System.String System.String Name ---Address Transport Port Hostname Enabled URLPrefix CertificateThumbprint ListeningOn_1038621592 ListeningOn_1770022257 ListeningOn_1055432771 ListeningOn_1414502903 ListeningOn_894013609 ListeningOn_1270366863 ListeningOn_1565265845 ListeningOn_2078661606 ListeningOn_1147683958 SourceOfValue ------------- PS WSMan:\localhost\Listener\Listener_1084132640> Value ----* HTTP 5985 true wsman 10.168.133.49 127.0.0.1 192.168.205.1 ::1 2001:4898:0:fff:0:5e... fe80::5efe:10.168.13... fe80::5efe:192.168.2... fe80::25a7:4656:665e... fe80::fc39:ec3b:d823... 185 ドメイン外のコンピューターを操作するには 操作元の「TrustedHost」リストにターゲットコンピューターを追加する ※「ターゲット」を管理対象としてもいいかを明記するってこと 操作元 ターゲット Trusted Hosts Windows Management Active Directory ドメイン Or ワークグループ WinRM Litener Windows Firewall Credential で認証 OS ワークグループ or Active Directory ドメイン 186 PS C:\> Get-Item wsman:\localhost\Client\TrustedHosts WSManConfig: Microsoft.WSMan.Management\WSMan::localhost\Client Type ---System.String Name ---TrustedHosts SourceOfValue Value ----------------規定では未設定 PS C:\> Set-Item wsman:\localhost\Client\TrustedHosts 192.168.205.* -Concatenate WSManConfig: Microsoft.WSMan.Management\WSMan::localhost\Client Type ---System.String Name ---TrustedHosts SourceOfValue ------------- Value ----192.168.205.* 187 TIPS:NIC のプロファイルが「識別されていない」場合 識別されていない = “パブリックネットワーク” である • ターゲットが Windows クライアント(Windows 7/8 等)であれば、ターゲッ ト PC で以下を実行(Server の場合には行う必要なし) Enable-PSRemoting -Force -SkipNetworkProfileCheck 188 リモーティング編 7. -ComputerName パラメタの利用 189 リモートコンピュータの操作する3つの方法 <コマンドレット> -ComputerName パラメタ ※ -ComputerName では PSセッションは張られない • リモートコンピューターに対して「リモート」から操作を行う • 複数のコンピュータを指定可能 Invoke-Command -ComputerName ・・・・・ • -ComputerName パラメタをもたないコマンドレットに対応 • リモートコンピューターの「中」で処理を行う • 複数のコンピュータを指定可能 • コマンドやスクリプトの終了と同時にセッションと接続は消滅 Enter-PSSession -ComputerName ・・・・・ • 対話モード(SSH のような使い方) • Exit コマンドで接続を切断し、セッション消滅 190 -ComputerName を持つコマンドレット PS C:\> Get-Command -CommandType Cmdlet -ParameterName ComputerName (ほんの一部) Invoke-Command New-PSSession Connect-PSSession Receive-PSSession Get-PSSession Remove-PSSession Receive-Job Enter-PSSession Add-Computer Clear-EventLog Get-EventLog Get-HotFix Get-Process Get-Service Get-WmiObject Invoke-WmiMethod Limit-EventLog New-EventLog Register-WmiEvent Remove-Computer Remove-EventLog Remove-WmiObject Rename-Computer Restart-Computer Set-Service Set-WmiInstance Show-EventLog Stop-Computer Test-Connection Write-EventLog Get-WindowsFeature Install-WindowsFeature Uninstall-WindowsFeature 191 -ComputerName の利用 リモートコンピューターのイベントログを取得する PS C:\> Get-EventLog -ComputerName tfdc02 -LogName Security -Newest 10 リモートコンピューターを再起動する PS C:\> Restart-Computer -ComputerName tfsv02 リモートコンピューターにインストールされている役割/機能の一覧 PS C:\> get-WindowsFeature -ComputerName tfsv02 リモートコンピューターに Hyper-V 管理ツールをインストールする PS C:\> Add-WindowsFeature -ComputerName tfsv02 -Name RSAT-Hyper-V-Tools -IncludeAllSubFeature -IncludeManagementTools 192 リモーティング編 8. PS セッション 193 リモートコンピュータの操作する 3 つの方法 <コマンドレット> -ComputerName パラメタ ※ -ComputerName では PSセッションは張られない • リモートコンピューターに対して「リモート」から操作を行う • 複数のコンピュータを指定可能 Invoke-Command -ComputerName ・・・・・ • -ComputerName パラメタをもたないコマンドレットに対応 • リモートコンピューターの「中」で処理を行う • 複数のコンピュータを指定可能 • コマンドやスクリプトの終了と同時にセッションと接続は消滅 Enter-PSSession -ComputerName ・・・・・ • 対話モード(SSH のような使い方) • Exit コマンドで接続を切断し、セッション消滅 194 “セッション” と “PS セッション” • Windows PowerShell の実行環境 Local Computer CALL セッション Remote Computer PSセッション PSセッション CALL セッション CALL セッション •PowerShell.exe が起動すると作られる。 •コンソールを閉じたらクリア。 •個々のセッションは独立 PSセッション CALL • • • Remote Computer PSセッション PSセッション ユーザー自身が作成し、管理と制御が可能 永続化が可能 個々のPSセッションは独立 195 PS セッション • PS セッション内でコマンドやスクリプトが実行される • 変数もセッション内に保存される • コネクションが「消滅」するとセッションも「消滅」する Source コネクション セ ッ シ ョ ン Target • テンポラリ PS セッション • -ComputerName を使用したときに作成されるセッション • コマンドが終了するとセッションも終了する • リユーザブル(Re-usable) PS セッション • コマンド終了後もコネクションを維持し、セッションを継続 • 実行中の変数等もそのまま維持される 196 Invoke-Command の特徴 • -ComputerName パラメタを持つ • どんなコマンドでもリモートで実行可能 • -ComputerName パラメタを持たないコマンドレット (Start-Service, Stop-Service など) • 従来の DOS コマンド(netstat や gpupdate など) • -Credential のサポート • コマンドレットの中には -Credential を持たないものが多い • -FilePath パラメタにスクリプトを指定可能 • スクリプトはローカルに存在していれば OK ※ただしコマンドレットはリモートに必要 • 複数のコンピューターを指定可能 197 Invoke-Command の利用 コマンドやスクリプトをリモートコンピューターに投げて、結果を受け取る Get-Service -ComputerName と同じ リモートコンピューターのサービス一覧を取得する PS C:\> Invoke-Command -ComputerName tfsv02 -ScriptBlock{ Get-Service } リモートコンピューターの Windows Update サービスを停止する PS C:\>Invoke-Command -ComputerName tfsv02 -ScriptBlock{ Stop-Service -Name wuauserv } リモートコンピューターで GPUpdate を実行する PS C:\>Invoke-Command -ComputerName tfsv02 -ScriptBlock{ GPUpdate.exe } リモートコンピューターの環境変数一覧を取得する PS C:\> Invoke-Command -ComputerName tfsv02 -ScriptBlock{ cd env: ; dir } 198 Invoke-Command -FilePath パラメタについて -FilePath パラメタに指定するスクリプト(.ps1)は、ローカルのパス Invoke-Command -ComputerName SV01 -FilePath .\hogehoge.ps1 hogehoge.ps1 Get-Service ・ ・ スクリプトの中身がリモートに送られる Target Computer Invoke-Command -ComputerName SV01 -ScriptBlock {.\hogehoge.ps1} ターゲット に存在しな いとエラー Target Computer hogehoge.ps1 199 リモートコンピューター上に仮想マシンを作成し起動する PS C:\> Invoke-Command -ComputerName "junichia-demo05" -FilePath ".\CreateVirtualMachine.ps1" -ArgumentList “Guest99",“2",“1024MB" CreateVirtualMachine.ps1 1 2 3 4 5 6 7 8 9 10 11 12 13 14 param([string] $VMName = "VM01", [int] $CPU = 1, [int] $Mem = 10MB) Stop-VM -Name $VMName -Force Remove-VM -Name $VMName -Force Remove-Item -Path \\junichia-vdi\VMs\$VMName -Recurse -Force $SwitchName = "Intel(R) 82579LM Gigabit Network Connection - Virtual Switch" New-VM -BootDevice CD ` -MemoryStartupBytes $Mem ` -Name $VMName ` -SwitchName $SwitchName ` -NewVHDPath \\junichia-vdi\VMs\$VMName\$VMName.vhdx ` -NewVHDSizeBytes 40GB Set-VM -ProcessorCount $CPU -DynamicMemory -Name $VMName Add-VMNetworkAdapter -VMName $VMName -SwitchName $SwitchName Start-VM -Name $VMName 200 Invoke-Command の注意点 • PS セッションは Invoke-Command ごとに作成され、実行後に消滅する PS> Invoke-Command -ComputerName Server1 -ScriptBlock {$A = 1} PS> Invoke-Command -ComputerName Server1 -ScriptBlock {$B = 1} PS> Invoke-Command -ComputerName Server1 -ScriptBlock {$C = $A + $B} PS> Invoke-Command -ComputerName Server1 -ScriptBlock {“$A=1; $B=2 ; $C=$A+$B” } 201 複数のリモートコンピューターに対する一括操作 • 複数のコンピューターに対して処理を行い、結果をマージして出力 • 非同期に処理が開始され、全ての処理が終了するまで待ち合わせる (シーケンシャルでないことに注意!) • 規定では最大同時32台 -ComuterName パラメタに複数のコンピューターを指定する PS > $ComputerList = “tfdc01”, “tfdc02” PS > Get-Service -ComputerName $ComputerList | Sort-Object MachineName, Name | Select-Object MachineName, Name, Status PS > $ComputerList = “tfdc01”, “tfdc02” PS > Invoke-Command -ComputerName $ComputerList {Get-Service |SortObject PSComupterName, Name | Select-Object PSComputerName, Name, Status} | FT MachineName と PSComputerName に注意! 202 $PSComputerName PSSession のターゲットとなったコンピューター名が格納される変数 Get-Service -ComputerName TARGET 結果 WMI 実 行 Source 空 間 Target Get-Service コマンドレットの 結果にはコンピューター名 (MachineName)が含まれる。 Invoke-Command -ComputerName TARGET { Get-Service } WMI Source コマンド 結果 実 行 空 間 Target Get-Service コマンドレットの結 果に含まれるMachineNameには ローカルコンピューター「.」が含 まれる。 Target コンピューター名を取得す るには $PSComputerName を使 用する。 203 CSVファイルから複数コンピューターを入力 HostName,IPAddress tfdc01,192.168.1.1 tfdc02,192.168.1.2 tfsv01,192.168.1.3 tfsv02,192.168.1.4 Invoke-Command -ComputerName (Import-CSV computerlist.txt).HostName {getculture} LCID ---1041 1041 1042 1041 Name ---ja-JP ja-JP ja-JP ja-JP DisplayName ----------日u本語e (日u本) 日u本語e (日u本) 日u本語e (日u本) 日u本語e (日u本) PSComputerName -------------tfdc01 tfdc02 tfsv02 tfsv01 204 Enter-PSSession • テンポラリ接続により対話型のセッションを開設する • 複数のコマンドを実行可能 • 接続が生きている間はセッションも行き続ける PS> Enter-PSSession -ComputerName Server1 [Server1]: PS > $A = 1 [Server1]: PS > $B = 2 [Server1]: PS > $C = $A + $B PS> Exit-PSSession 205 リモーティング編 9. コネクションの永続化と PS セッションの再利用 206 リユーザブルな PS セッションを使用するには • • • • セッションの作成 セッションの削除 セッション一覧 セッションへの接続 :New-PSSession :Remove-PSSession :Get-PSSession :Connect-PSSession セッションを作成 PS > $S = New-PSSession -ComputerName CL01 PS > Invoke-Command -session $S -ScriptBlock {$A=1} セッション内 PS > Invoke-Command -session $S -ScriptBlock {$B=2} PS > Invoke-Command -session $S -ScriptBlock {$C=$A+$B} で実行される PS > Enter-PSSession $S [CL01] PS > Echo $C [CL01] 3 PS > Exit-PSSession PS > Remove-Session $S 207 複数ターゲットを含んだコネクションも可能 Source コネクション シセ ョッ ン Target1 シセ ョッ ン Target2 PS > $S = New-PSSession -ComputerName CL01,CL02 PS > $S Id -80 81 Name ---Session80 Session81 ComputerName -----------tfdc01 tfdc02 State ----Opened Opened ConfigurationName ----------------Microsoft.PowerShell Microsoft.PowerShell Availability -----------Available Available PS > Invoke-Command -Session $S {Get-Culture} 208 ローカル変数をPSセッションで使用する 書式 $Using:<変数名> PS C:\> $S = New-PSSession -ComputerName tfdc01 PS C:\> $MyName = “Junichi Anno” PS C:\> Invoke-Command -Session $S {Echo $Using:MyName} Junichi Anno 209 PS セッション情報の取得 ~ Get-PSSession • リユーザブルなセッション情報は他のコンピューターからも参照できる • 他のユーザーが作成したセッションは、Credential が有効であれば参照可能 Source1 コネクション Source2 シ ョセ ンッ Target1 -Credential パラメタを使用可能 PS C:\tools\ps> Get-PSSession -ComputerName Target1 Id -65 80 109 Name ---tfdc01_Session Session80 Session109 ComputerName -----------target1 taeget1 target1 State ----Opened Opened Opened ConfigurationName ----------------Microsoft.PowerShell Microsoft.PowerShell Microsoft.PowerShell Availability -----------Available Available Available 210 PS セッションへの再接続 • リユーザーブルな PS セッションには他のコンピューターから再接続が可能 • State=Disconnected, Availability=None に対してのみ • Disconnect-PSSession コマンドレットで明に Disconnect した場合 • ネットワークの切断や PC のハングアップ等で Disconnected になった場合 ※ コンソールを明に落とした場合は強制終了したものとみなされる • 同時に2台以上のコンピューターからは接続できない State=Disconnected Availability=None Source1 Source2 Disconnect-PSSession Connect-PSSession 再接続可能 セ ッ シ ョ ン Target1 211 PC 1 PS > $S = New-PSSession -ComputerName Target1 PS > $Result = Invoke-Command -Session $S {Get-Service} PS > Disconnect-PSSession -Session $S Id Name -- ---121 Session121 ComputerName -----------Target1 State ----Disconnected ConfigurationName ----------------Microsoft.PowerShell Availability -----------None Target PS > Get-PSSession -ComputerName Target1 PC 2 Id Name -- ---10 Session112 12 Session121 ComputerName State ---------------tfdc01 Disconnected tfdc01 Disconnected ConfigurationName ----------------Microsoft.PowerShell Microsoft.PowerShell Availability -----------Busy None PS > $S = Get-PSSession -Name Session121 -ComputerName Target1 PS > Connect-PSSession -Session $S 212 State と Availability Id Name -- ---10 Session112 12 Session121 ComputerName -----------tfdc01 tfdc01 State Availability State ----Disconnected Disconnected ConfigurationName ----------------Microsoft.PowerShell Microsoft.PowerShell Availability -----------Busy None Opened 自分自身が接続している Disconnected 自分自身は接続していない None 誰も接続していない Busy 他の誰かが接続してる Available 自分が接続している 再わこ 接せの 続な組 可らみ 能ば合 213 もしソース PC がダウンしたら ソースが死んでもセッション情報はターゲットに残されている...ただし... Id Name -- ---10 Session112 ComputerName -----------tfdc01 State ----Disconnected ConfigurationName ----------------Microsoft.PowerShell Availability -----------Busy Availability が Busy なので、再接続できない 2 分 後 Id Name -- ---10 Session112 ComputerName -----------tfdc01 State ----Disconnected ConfigurationName ----------------Microsoft.PowerShell Availability -----------None 再接続可能! 214 PS セッションの有効期間 • PS セッションのターゲットの再起動、シャットダウン • Remove-PSSession を実行するまで PS > Remove-PSSession -Session $S • セッションがアイドルタイムアウトするまで • Disconnect してからの時間 規定値 PS C:\> Get-PSSessionConfiguration | ft name,idletimeoutms,maxidletimeoutms Name ---microsoft.powershell microsoft.powershell.workflow microsoft.powershell32 microsoft.windows.servermanagerworkflows IdleTimeoutms ------------7200000 2時間 7200000 7200000 180000 MaxIdleTimeoutms ---------------2147483647 596時間 2147483647 2147483647 180000 215 アイドルタイムアウト値の変更 設定方法 • 構成ファイルを変更 • Register-PSSessionConfiguration -TransportOption <$TransportOption> • Set-PSSessionConfiguration -TransportOption <$TransportOption> • PS セッション作成時(特定のセッションのみ) • New-PSSession -SessionOption <$SessionOption> • コマンド実行開始時(特定のセッションのみ) • Invoke-Command -SessionOption <$SessionOption> • PS セッション切断時(特定のセッションのみ) • Disconnect-PSSession -IdeleTimeOutSec <秒> PS C:\> $SessionOption = New-PSSessionOption -IdleTimeOutMSec 60000 PS C:\> $S = New-PSSession -ComputerName Target1 -SessionOption $SessionOption 216 出力バッファモード 出力バッファがFULLになった場合の対応モード • Block : バッファがClearされるまでコマンドの実行をサスペンドする • Drop:コマンドの実行は続けるが古い出力結果から捨てられる 現在のモードを調べる PS C\> Get-PSSessionConfiguration | ft Name, OutputBufferingMode Name ---microsoft.powershell microsoft.powershell.workflow microsoft.powershell32 microsoft.windows.servermanagerworkflows OutputBufferingMode ------------------Block Block Block Block 「現在の PS セッションでは Drop モードで実行する」を設定 PS C:\> $o = New-PSSessionOption -OutputBufferingMode Drop PS C:\> New-PSSession -SessionOption $o 217 ループバック PS セッション • LOCALHOST に対してリユーザーブルな PS セッションを作成すれば、 切断したあと別のマシンから再接続が可能 • 管理者モードで実行する必要がある Source2 Connect-PSSession 再接続可能 セ ッ ンシ ョ Source1 /Target PS> $S = New-PSSession -Name Backup PS> Invoke-Command -Session $S -FilePath backup.ps1 -AsJob PS> Disconnect-PSSession -Session $S PS > $S = Get-PSSession -ComputerName localhost -Name Backup PS > Receive-PSSession -Session $S PS > Remove-PSSession -Session $S 218 モジュールとコマンドのインポート • リモートコンピューター上のコマンドレットを一時的に取り込むことができる • “Invoke-Command -Session” を使用する必要が無くなる • コマンドの実行中はセッションを生かしておく必要がある PS C:\> Get-VM |ft name Name ---VM01 VM02 VM03 VM04 VM05 Hyper-V Module PS Session Windows Server w/ Hyper-V PS C:> $s = New-PSSession -ComputerName Server1 PS C:> Import-PSSession -Session $s -Module HYPER-V 219 リモーティング編 10. PSWA 220 Windows PowerShell Web Access WS-Man に接続するためのゲートウェイ Internet Home Intranet DMZ 再接続 221 PowerShell Web Access のセットアップ 1.サーバーマネージャーから PowerShell Web Access をインストールする 222 2.IIS で自己署名証明書を作成してバインドを設定する(SSLを有効に) ご自身のサーバーを指 定してください バインドの設定で 作成した証明書を選択 223 2.PowerShell を管理者モードで起動 3.以下のコマンドを実行 PS C:\> Set-ExecutionPolicy RemoteSigned PS C:\> Import-Module PowerShellWebAccess PS C:\> Install-PswaWebApplication -webSiteName "Default Web Site" PS C:\> Add-PswaAuthorizationRule * * * 4.https://<サーバー名>/pswa にアクセス ここで指定するサーバーは、 ターゲットとなるサーバー 224 Part 3 バックグラウンドジョブ編 225 バックグラウンドジョブ • Windows PowerShell 2.0 よりサポート • 長時間を要するコマンドレットを非同期に実行し、次の処理に移る (例)get-eventlog “Security” • ジョブの有効範囲は現在のセッション • ジョブを生成するには – – -AsJob パラメタ • 一部のコマンドのみが実装 • ワークフローコマンドには使用可能 Start-Job コマンドレット • すべてのコマンド、スクリプトをジョブ化可能 • ジョブの結果がどこに保存されるのかを意識することが重要! 226 -AsJob -AsJob パラメタを持つコマンドレットは少ない PS C:\> Get-Command -ParameterName asjob CommandType ----------Function Function Function Function Function Function Function Function Function Function Function Cmdlet Cmdlet Cmdlet Cmdlet Cmdlet Cmdlet Cmdlet Cmdlet Name ---Get-SMCounterSample Get-SMPerformanceCollector Get-SMServerBpaResult Get-SMServerClusterName Get-SMServerEvent Get-SMServerFeature Get-SMServerInventory Get-SMServerService Remove-SMServerPerformanceLog Start-SMPerformanceCollector Stop-SMPerformanceCollector Get-WmiObject Invoke-Command Invoke-WmiMethod Remove-WmiObject Restart-Computer Set-WmiInstance Stop-Computer Test-Connection ※AsJobパラメタを持つコマンド一覧 ModuleName ---------ServerManagerTasks ServerManagerTasks ServerManagerTasks ServerManagerTasks ServerManagerTasks ServerManagerTasks ServerManagerTasks ServerManagerTasks ServerManagerTasks ServerManagerTasks ServerManagerTasks Microsoft.PowerShell.Management Microsoft.PowerShell.Core Microsoft.PowerShell.Management Microsoft.PowerShell.Management Microsoft.PowerShell.Management Microsoft.PowerShell.Management Microsoft.PowerShell.Management Microsoft.PowerShell.Management 227 ジョブ関連のコマンドレット Get-Job バックグラウンドジョブを取得 Receive-Job バックグラウンドジョブの出力結果を取得 Remove-Job バックグラウンドジョブを削除 Start-Job バックグラウンドジョブを開始 Stop-Job バックグラウンドジョブを停止 Wait-Job バックグラウンドジョブが終了するまで待つ 228 バックグラウンドジョブの基本操作 書式 start-job -scriptblock { <スクリプトブロック> } 5秒に1回日時を表示するジョブ (例) PS C:\> $job = start-job -scriptblock {do {$a = 0; echo (date) ; start-sleep 5} while ($a -eq 0) } PS C:\> $job 出力結果が存在する Id -6 Name ---Job6 State ----Completed PS C:\> Receive-Job $job -Keep PS C:\> Stop-Job $job PS C:\> Remove-job $job HasMoreData ----------True Location -------localhost Command ------get-eventlog "Windows ... 規定では、出力結果は一度取得するとクリアされてしま うので、-Keep によって残すように指定 ジョブを停止 ジョブを削除 229 スクリプトをバックグラウンドジョブ化するには まずはスクリプトを作成する(イベントログを取得するスクリプト) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 $flg = $true WatchNewEventLog.ps1 $index = 0 $index_old = 0 Do { $Eventlog = Get-Eventlog -LogName TechFielders -Source TechFielders $index = $eventlog | Select-Object -First 1 -Property Index $delta_index = $index.Index - $index_old if ($delta_index -gt 0) { $eventlog | ` Select-Object -First $delta_index | ` Sort-Object -Property Index } 結果を Index をキーとして昇順に並べる Start-Sleep -Seconds 1 $index_old = $index.Index } While ($flg) 230 ##作成したスクリプトをバックグラウンドで実行する PS C:\> Start-Job -FilePath .\WatchNewEventLog.ps1 -Name WatchNewEventLog Id -4 Name PSJobTypeName ---------------WatchNewEven... BackgroundJob State ----Running HasMoreData ----------True Location -------localhost Command ------$flg = $true... 以下のコマンドで新しいイベントを書き込む C:\> Write-EventLog -LogName TechFielders -Message "Hello" -Source "TechFielders" -EventId 5963 ## 以下のコマンドで現在までの結果を収集する PS C:\> Receive-Job -Name WatchNewEventLog Index Time EntryType Source InstanceID Message ----- ------------ --------------- ------1 6 02 17:41 Information TechFielders 5963 テスト 2 6 02 18:09 Information techfielders 99 テスト 3 6 02 18:11 Information TechFielders 9909 テスト 4 6 02 18:12 Information TechFielders 9909 テスト 5 6 02 18:13 Information TechFielders 9909 テスト 6 6 02 18:13 Information TechFielders 9909 Hello 231 “ジョブの実行場所”と”結果の保存場所”は一緒の法則 • “コマンドの実行場所”と”ジョブの実行場所”は異なる可能性がある • 操作のターゲットがリモートコンピューターであっても、 ジョブがローカルならば結果もローカルに保存される Session CmdLet Job/Result コマンドはリモート ジョブはローカル Source Source Job/Result Session CmdLet コマンドはリモート ジョブもリモート Target Target 232 セッションの永続化とジョブの実行結果 (例1)Invoke-Command -AsJob を使用した場合 スクリプトはリモートだが、ジョブはローカル。 Invoke-Command の結果はローカルに保存されることに注意!!! つまりローカルセッションが消えたらジョブの結果も消えるということ!! 結 果 SRC 実 行 Invoke-Command をバックグ ラウンドジョブ化するため のオプション。 Target PS> Invoke-Command -Session $S -FilePath backup.ps1 -AsJob Id -2 Name ---Job2 PSJobTypeName ------------RemoteJob State ----Completed HasMoreData ----------True Location -------tfdc01 Command ------get-service PS> Receive-Job -Id 2 セッションに再接続する場合には、結果もリモートに保存しなければ意味がない!! 233 (例2)Invoke-Command {Start-Job} を使用した場合 スクリプトをジョブ化することで、結果がリモートに保存されるため、セッションを永続化すれ ば別のコンピューターから取り出せる。 実 結 行 果 SRC1 Target SRC2 PS> $S = New-PSSession -ComputerName Target -Name Backup PS> $Script = “.\testscript.ps1" PS> Invoke-Command -Session $S { Start-Job -FilePath $Script } Id -1 Name ---Job1 PSJobTypeName ------------BackgroundJob State ----Running HasMoreData ----------True Location -------localhost Command ------backup... PS> Disconnect-PSSession -Session $S (つづく) 234 別のコンピューターから接続して結果を取得 PS> Get-PSSession -ComputerName tfdc01 Id Name -- ---1 backup ComputerName -----------tfdc01 State ----Disconnected ConfigurationName Availability ----------------------------Microsoft.PowerShell None PS> $S = Connect-PSSession -Name backup -ComputerName tfdc01 PS> Invoke-Command -Session $S { Get-Job } Id -1 Name ---Job1 PSJobTypeName ------------BackgroundJob State ----Completed HasMoreData ----------True Location -------localhost PS> Invoke-Command -Session $S {Receive-Job -Id 1} 235 バックグラウンドジョブのスケジューリング • PSScheduledJob モジュールで提供 Add-JobTrigger Disable-JobTrigger Disable-ScheduledJob Enable-JobTrigger Enable-ScheduledJob Get-JobTrigger Get-ScheduledJob Get-ScheduledJobOption New-JobTrigger New-ScheduledJobOption Register-ScheduledJob Remove-JobTrigger Set-JobTrigger Set-ScheduledJob Set-ScheduledJobOption Unregister-ScheduledJob 236 ジョブスケジューリングの例 $trigger = New-JobTrigger -Daily -At 3am Register-ScheduledJob -Name EnergyAnalysisJob -Trigger $trigger -ScriptBlock { powercfg.exe -energy -xml -output C:\temp\energy.xml -duration 60 | Out-Null $EnergyReport = [xml](get-content C:\temp\energy.xml) $namespace = @{ ns = "http://schemas.microsoft.com/energy/2007" } $xPath = "//ns:EnergyReport/ns:Troubleshooter/ns:AnalysisLog/ns:LogEntry[ns:Severity = 'Error']" $EnergyErrors = $EnergyReport | Select-Xml -XPath $xPath -Namespace $namespace $EnergyErrors.Node | select Name, Description } タスクマネージャーで参照可能 237 Part 4 ワークフロー編 238 Agenda ~ワークフロー編 11.Windows PowerShell Workflow とは 12.Windows PowerShell Workflow の基礎 13.ワークフロー特有の記述 14.ワークフロージョブとデータの永続化 239 ワークフロー編 12. Windows PowerShell Workflow とは 240 想定している利用シーン ターゲットとなる処理 要求される制御機構 • 長時間を要する処理 • • • • – 仮想マシンの展開 – ソフトウェアのインストール – ビッグデータの集計 など • 複数の処理の組み合わせ • 複数のコンピューターに対する処理 – ドメイン参加 – 環境設定 – インベントリ収集 など タイムアウトやリトライ 処理の一時停止、再開 処理ステートの永続化 複数処理の制御 • 並列 • シーケンシャル • スクリプト実行権限の委任 • 途中経過の取得 ワークフロー = バックグラウンドジョブ + リモーティング + 実行制御 241 (例)ユーザーを作成する ユーザーごとの処理 パスワード 設定 UserList ユーザー リストを チェック ユーザー 作成 グループメン バーシップ ユーザー 属性設定 ホームディレ クトリ作成 完了 アクセス権 設定 242 PowerShell 3.0 - ワークフロー 処理1 checkpoint 処理2 結果1 サスペンド サーバー ダウン checkpoint WF パラレル 処理3 WF 処理1 結果ストア ジョブと結果の永続化 処理2 WF サーバーが条件 に合致しない場 合にサスペンド し、あとでレ ジューム サスペンド 243 PowerShell ワークフローの特長 • 実行中のコンピューターが再起動してもワークフロージョブは消えない • 一時停止状態(Suspend)になる • 長時間タスクの制御と監視 • アクティビティの進行状況はいつでも参照可能 • 自動リカバリ • 途中経過は指定したポイントで保存されている • ワークフローセッションへの接続と切断 • ワークフローを開始した PC とは別の PC から再接続が可能 • 同時に複数コンピューターへの接続 • ワークフロータスクを同時に大量のサーバーに配信可能 • 複数のスクリプトを1つのワークフローでコントロール • スケジューリング • 特定の状態をトリガーとして起動可能 • XAMLファイルでインポート、エクスポート可能 ※ ワークフローが動作するコンピューターには Windows PowerShell 3.0 が必須 244 ワークフロー編 13. Windows PowerShell Workflow の基礎 245 ワークフロ―実行までの流れ ① ワークフローを作成する ② ワークフローを登録する ③ ワークフローを確認する ④ ワークフローを実行する i. ワークフローセッションの作成 ii. ワークフローを実行 iii. 結果を取得 246 Wokflow の作成 • PowerShell ISE(またはテキストエディタ) で作成する • workflow キーワードを使用する workflow <ワークフロー名> ( <引数> ) { <処理> } (例)MyWorkflow という名前でリモートコンピューターのサービス一覧を取得するワークフロー workflow MyWorkflow ( [String] $ServiceName ) { 共通パラメタ(後述) Get-Service -PSComputerName $PSComputerName -Name $ServiceName } 注意 -ComputerName ではない(後述) 247 Workflow の登録 • .ps1 で保存し、実行するだけ または、PowerShell ISE 上から実行するだけ • 留意点 どこに登録するか? いつ登録するか? 248 Workflow をどこに登録するか? ワークフローは実行するノードに存在しなければならない In-Process Execution 終わるまで家に帰れない! WMI WinRM Managed Node WMI WinRM WF WF 自分のPC Managed Node Execution in Workflow Configuration 実行したらセッッション切断して帰宅 :) 自分のPC WF 実行 249 Workflow の登録先と実行環境について • In-process 実行 Activity はローカルに登録される PowerShell クライアントホスト上での実行 ワークフローが終了するまでセッションを切断できない • Workflow セッション上での実行 Activity はリモートノードに登録される Workflow 用に PS セッションを作成し、WinRM を通して実行する 一時的な切断が可能で、長時間のジョブを実行する際に便利 250 (参考)In-Process 実行時のアーキテクチャ Localhost Managed Node Activity Host Process Activity Host PowerShell Remoting (RSRP) Managed Node PSWF Cmdlets PSWF Executive CIMOM/ WMI Powershell.exe 251 (参考)Workflow セッションで実行時のアーキテクチャ Client PowerShell Workflow PSJobProxy/ PSJob API/ PSRP Managed Node Activity Host Process Activity Host PowerShell Remoting (RSRP) Managed Node WinRM Client WinRM Service PSWF Executive CIMOM/ WMI 252 • リモートノードにワークフローを登録 =リモートでスクリプトを実行 PS1ファイルがローカルにある場合 実行 WMI WMI WinRM WMI WinRM WinRM Proxy Node WinRM 登録 WF 自分のPC Managed Managed Node Managed Node Node PS C:\> $S = New-PSWorkflowSession -ComputerName <Node> PS C:\> Invoke-Command –Session $S -FilePath mywf.ps1 PS1ファイルがリモートにある場合 ワーククフローが定義されているファイル PS C:\> $S = New-PSWorkflowSession -ComputerName <Node> PS C:\> Invoke-Command –Session $S { .\mywf.ps1 } 253 ワークフローをいつ登録すべきか? 注意 ワークフローは セッション または PSセッション 内でのみ有効 ダメな例1:コンソールを閉じた瞬間に消滅 orz PS C:\>.\mywf.ps1 ダメな例2:登録したとたんに消滅 PS C:\> Invoke-Command -ComputerName NODE -FilePath .\mywf.ps1 PS C:\> Invoke-Command -ComputerName NODE -FilePath .\mywf.ps1 -asjob ダメじゃないけど気をつけなければならない例:PS セッション消滅とともにWF も消滅 PS C:\> $S = New-PSSession -ComputerName NODE PS C:\> Invoke-Command -Session $S -FilePath .\mywf.ps1 ワークフローは実行直前に登録したほうがよさそう... 254 (参考)workflow を登録すると... .ps1 ファイル workflow { Get-Service } 実行 AST(abstract syntax tree) “workflow” キーワード検出 Script-to-workflow コンパイラ XAML ActivityXamlService Class workflow Activity Tree Workflow Foundation 4 255 登録されたワークフローの確認 • Get-Command で確認する (ワークフローはコマンドレットと同じように扱える) PS C:\> Get-Command <ワークフロー名> PS C:\> Get-Command MyWorkflow CommandType ----------Workflow Name ---MyWorkflow ModuleName ---------- 256 (参考)ワークフローに登録されるラッパー関数の確認 PS C:\> Get-Command MyWorkflow |Get-Member TypeName: System.Management.Automation.WorkflowInfo Name ---Equals GetHashCode GetType ResolveParameter ToString CmdletBinding ・ ・ ・ RemotingCapability ScriptBlock Verb Visibility WorkflowsCalled XamlDefinition HelpUri MemberType ---------Method Method Method Method Method Property Definition ---------bool Equals(System.Object obj) int GetHashCode() type GetType() System.Management.Automation.ParameterMetada... string ToString() bool CmdletBinding {get;} Property Property Property Property Property Property ScriptProperty System.Management.Automation.RemotingCapabil... scriptblock ScriptBlock {get;} string Verb {get;} System.Management.Automation.SessionStateEnt... System.Collections.ObjectModel.ReadOnlyColle... string XamlDefinition {get;} System.Object HelpUri {get=$oldProgressPrefe... 257 (参考)XAML の確認 PS C:\> (Get-Command MyWorkflow).XamlDefinition <Activity x:Class="Microsoft.PowerShell.DynamicActivities.Activity_267955735" xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities" xmlns:sad="clr-namespace:System.Activities.Debugger;assembly=System.Activities" xmlns:local="clr-namespace:Microsoft.PowerShell.DynamicActivities" xmlns:mva="clr-namespace:Microsoft.VisualBasic.Activities;assembly=System.Activities" mva:VisualBasic.Settings="Assembly references and imported namespaces serialized as XML namespaces" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ns0="clr-namespace:System;assembly=mscorlib" xmlns:ns1="clr-namespace:Microsoft.PowerShell.Activities;assembly=Microsoft.PowerShell.Activities" xmlns:ns2="clr-namespace:System.Activities;assembly=System.Activities" xmlns:ns3="clr-namespace:Microsoft.PowerShell.Management.Activities;assembly=Microsoft.PowerShell.Management.Activities" > <x:Members> <x:Property Name="ServiceName" Type="InArgument(ns0:String)" /> </x:Members> <Sequence> <ns1:SetPSWorkflowData> <ns1:SetPSWorkflowData.OtherVariableName>Position</ns1:SetPSWorkflowData.OtherVariableName> <ns1:SetPSWorkflowData.Value> <ns2:InArgument x:TypeArguments="ns0:Object"> <ns1:PowerShellValue x:TypeArguments="ns0:Object" Expression="'3:2:MyWorkflow'" /> </ns2:InArgument> </ns1:SetPSWorkflowData.Value> </ns1:SetPSWorkflowData> <ns3:GetService> <ns3:GetService.PSComputerName> <ns2:InArgument x:TypeArguments="ns0:String[]"> 258 ワークフローの実行 コマンドレットと同じように実行すればよい PS C:\> MyWorkflow 留意点 • どこで実行するか? ローカルで実行するとローカルコンピューターは落とせない • どこに結果を蓄積するか? 結果を蓄積するコンピューターは落とせない 複数のコンピューターに結果が散在すると結果を得るのが面倒 • 「共通パラメタ」を使用する必要がある 259 復習~バックグラウンドジョブ -AsJob の場合 Invoke-Command ーSession $S { ..... } -AsJob SRC 結 果 実 行 Target 結果はローカルに戻される Start-Job を使用する場合 Invoke-Command { Start-Job ・・・・} SRC1 実 結 行 果 Target 結果はリモートに保存される。セッションを永続化 すれば別のコンピューターから取り出せる。 SRC2 260 (推奨)リモートで実行し、1箇所に結果を集める Invoke-Command ーSession $S { WorkflowName -AsJob } 事前にワークフローを 登録しておく ローカル PC1 ローカル PC2 リモート サーバー PSWorkflowSession 実行支持 実 行 PSWorkflowSession 結果を参照 結 果 実 行 Managed Node 実 行 Managed Node 実 行 Managed Node 実 行 Managed Node 261 ワークフローの実行例 登録されているワークフロー workflow MyWorkflow ( [String] $ServiceName ) { Get-Service -PSComputerName $PSComputerName -Name $ServiceName } 1. Workflow セッションを作成 C:\> $S = New-PSWorkflowSession -ComputerName PROXYNODE 2. Workflow をリモートで実行 (リモートに Workflow が登録されている必要がある) C:\>Invoke-Command $S { MyWorkflow -ServiceName WinRM ジョブとして実行 -PSComputerName TARGET1,TARGET2,TARGET3 -AsJob } 共通パラメタ 結果は、-PSComputerName で 指定したコンピューター個々 に保存される 3. Workflow セッションを切断(セッションは生かしておく) C:\> Disconnect-PSSession $S 262 New-PSWorkflowSession • 規定では New-PSSession で作られる PS セッションと同じ設定 • ワークフロー用に構成情報を独自に設定することができる PS C:\> (New-PSworkflowSession).ConfigurationName Microsoft.PowerShell.Workflow PS C:\> Get-PSSessionConfiguration Microsoft.PowerShell.Workflow Name PSVersion StartupScript RunAsUser Permission : microsoft.powershell.workflow : 3.0 : : : BUILTIN\Administrators AccessAllowed, BUILTIN\Remote Management Users AccessAllowed PS C:\> (New-PSSession).ConfigurationName Microsoft.PowerShell PS C:\> Get-PSSessionConfiguration Microsoft.PowerShell Name PSVersion StartupScript RunAsUser Permission : microsoft.powershell : 3.0 : : : BUILTIN\Administrators AccessAllowed, BUILTIN\Remote Management Users AccessAllowed 263 PSWorkflow モジュール • Windows PowerShell WorkFlow セッション を管理するためのモジュール • 2つのコマンドレット New-PSWorkflowSession • ワークフロー用 PS セッションを作成する New-PSWorkflowExecutionOption • ワークフローセッションの構成情報を含んだオブジェクトを作成する 264 共通パラメタとは • • • • ワークフロー内部、引数で使用できる特殊なパラメタ ワークフローの処理を効率化するために用意されている “PS” で始まる コマンドレットのパラメタ名も同様に変わることに注意 通常のスクリプト Get-WmiObject -Class Win32_ComputerSystem -ComputerName TARGET01 -Credential $PSCredentials Workflow Get-WmiObject -Class Win32_ComputerSystem -PSComputerName TARGET01 -PSCredential $PSCredentials 265 workflow MyWorkflow { Get-WmiObject -Class Win32_ComputerSystem -PSComputerName $PSComputerName -PSCredential $PSCredential } パラメタ名も共通パラメ パラメタ名も 共通パラメタにあわせる タにあわせる 共通パラメタは引数を定 共通パラメタは、引数を 義する必要は無い 定義する必要が無い C:\>MyWorkflow -PSComputerName SV01,SV02,SV03,SV04 -PSCredential tf\administrator 266 PS ワークフローの共通パラメタ ワークフローの中で使用するためのパラメタで、既定の変数名でアクセスできる パラメタ名 意味 PSParameterCollection PSComputerName ターゲットコンピューター。複数指定すると、複数のコンピューターでワークフローが 同時実行される。 PSCredential ターゲットコンピューターに接続するための資格情報 PSConnectionRetryCount ターゲットコンピューターに再接続を試みる回数 PSConnectionRetryIntervalSec 再接続までの時間間隔 PSRunningTimeoutSec ワークフローが終了するまでの制限時間。制限時間がくるとワークフローは強制終了さ れる。ワークフローが一時停止していた場合には、その時間は実行時間には含まれない。 PSPersist $True または $False。ワークフロー内部で出力した結果を永続化する。 PSAuthentication 使用する認証のメカニズムを指定する。 Default / None / Connect / Call / Packet / PacketIntegrity / PacketPrivacy PSApplicationName ターゲットコンピューターに接続するために使用する接続URIのアプリケーション名を 指定する。既定は WSMAN。 PSPort リモートコンピューターに接続する際のポート番号。既定では5985(WinRM for HTTP)または5986(WinRM for HTTPS)。 267 パラメタ名 意味 PSUseSSL リモートコンピューターとSSLを使用して接続する PSConfigurationName ワークフローの構成情報が格納された構成名を指定する。規定値は Microsoft.PowerShell PSConnectionURI 接続に使用するエンドポイントを指定する。規定は http://localhost:5985/WSMAN PSAllowRedirection ターゲットコンピューターがURIのリダイレクトを要求してきたときに、それを PowerShell が許可するかどうかを指定する。規定値は $False。 PSSessionOption New-PSSessionOption で作成された拡張オプションを指定する。 PSCertificateThumbprint 権限を持ったX.509証明書のサムプリントを指定する PSPrivateMetadata ワークフローの実行時に使用される、ユーザーやアプリケーションの情報が格納された ハッシュテーブルを指定する AsJob ワークフローをバックグラウンドジョブとして実行する際に指定する。このオプション を使用すると、ジョブ情報がオブジェクトとして返されるので、これを使用して関連モ マンドレット(*-job)でジョブの制御を行うことができる。 JobName AsJobパラメタで実行した場合、規定では Job<n> という名前が付けられるが、このパ ラメタを使用してわかりやすいジョブ名を指定することができる。 InputObject ワークフローの引数 268 ワークフロージョブの確認と結果の取得 バックグラウンドジョブと同様の手法で取得する PS C:\> Invoke-Command -Session $S { Get-Job } Id -1 Name ---Job1 注意 PSJobTypeName ------------PSWorkflowJob State ----Completed HasMoreData ----------True Location -------tfdc02,tfsv01,tfsv02 PS C:\> Invoke-Command -Session $S { Receive-Job -Id 1 -Keep } Status -----Running Running Running Name ---WinRM WinRM WinRM DisplayName PSComputerName -----------------------Windows Remote Management (WS-Manag... tfdc01 Windows Remote Management (WS-Manag... tfdc01 Windows Remote Management (WS-Manag... tfdc01 269 ここで...JOB オブジェクトについて 各ノード(Location)ごとの処理は、ChildJob として管理されている PS C:\> $JOB = Invoke-Command -Session $S { Get-Job } Deserialized.System.Management.Automation.ContainerParentJob PS C:\> $JOB Id -1 Name ---Job1 PSJobTypeName ------------PSWorkflowJob PS C:\> $JOB.ChildJobs Id -2 3 4 Name ---Job2 Job3 Job4 State ----Completed HasMoreData ----------True Location -------tfdc02,tfsv01,tf... Deserialized.Microsoft.PowerShell.Workflow.PSWorkflowJob PSJobTypeName ------------PSWorkflowJob PSWorkflowJob PSWorkflowJob State ----Completed Completed Completed HasMoreData ----------True True True Location -------tfdc02 tfsv01 tfsv03 JOBを実行 した場所 270 PS C:\> $JOB |Get-Member TypeName: Deserialized.System.Management.Automation.ContainerParentJob Name ---ToString PSComputerName PSShowComputerName RunspaceId State ChildJobs Command HasMoreData Id InstanceId JobStateInfo Location Name PSBeginTime PSEndTime PSJobTypeName StatusMessage MemberType ---------Method NoteProperty NoteProperty NoteProperty NoteProperty Property Property Property Property Property Property Property Property Property Property Property Property Definition ---------string ToString(), string ToString(string format, System.IFor... System.String PSComputerName=tfdc01 System.Boolean PSShowComputerName=True System.Guid RunspaceId=ebcb1d6d-60b6-460b-b2b4-23a065bab884 System.String State=Completed Deserialized.System.Collections.Generic.List`1[[System.Manage... System.String {get;set;} System.Boolean {get;set;} System.Int32 {get;set;} System.Guid {get;set;} System.Management.Automation.JobStateInfo {get;set;} System.String {get;set;} System.String {get;set;} System.DateTime {get;set;} System.DateTime {get;set;} System.String {get;set;} System.String {get;set;} 271 ワークフロー結果の取得(再び) PS C:\> Invoke-Command -Session $S {Get-Job -IncludeChildJob} Id -1 2 3 4 Name ---Job1 Job2 Job3 Job4 PSJobTypeName ------------PSWorkflowJob PSWorkflowJob PSWorkflowJob PSWorkflowJob State ----Completed Completed Completed Completed HasMoreData ----------False False False False Location -------tfdc02,tfsv01,tfsv03 tfdc02 tfsv01 tfsv03 Command -----myw... MyW... MyW... MyW... PS C:\> Invoke-Command -Session $S {Receive-Job -Job (Get-Job -Id 4) -Keep} または PS C:\> Invoke-Command -Session $S {Receive-Job -Job (Get-Job) -Location tfsv02 -Keep } 272 ワークフロー編 14. Windows PowerShell Workflow 特有の記述 273 基本動作 ワークフロー 実行結果 workflow MyWorkflow { Start-Sleep -Second 1 Get-Date Start-Sleep -Second 1 Get-Date Start-Sleep -Second 1 Get-Date } PS C:\> MyWorkflow 上 か ら 順 番 に 実 行 2012年6月18日 18:35:00 2012年6月18日 18:35:01 2012年6月18日 18:35:02 PS C:\> 274 ワークフロー workflow MyWorkflow { Start-Sleep -Second 1 Echo -InputObject "$PSComputerName $(Get-Date)" Start-Sleep -Second 1 Echo -InputObject "$PSComputerName $(Get-Date)" Start-Sleep -Second 1 Echo -InputObject "$PSComputerName $(Get-Date)" } 実行結果 PS C:\> MyWorkflow -PSComputerName tfsv01,tfsv02 tfsv01 06/18/2012 18:43:58 tfsv02 06/18/2012 18:43:58 tfsv01 06/18/2012 18:43:59 tfsc02 06/18/2012 18:43:59 tfsv01 06/18/2012 18:44:00 tfsv02 06/18/2012 18:44:00 複数のコンピューターを指定した場合には、処 理自体はシーケンシャルだがコンピューター単 位で非同期に実行される 275 並列処理 ワークフロー workflow MyWorkflow { Get-Date parallel{ Start-Sleep -Second 1 Echo -InputObject "1 $PSComputerName $(Get-Date)" Start-Sleep -Second 1 Echo -InputObject "2 $PSComputerName $(Get-Date)" Start-Sleep -Second 1 Echo -InputObject "3 $PSComputerName $(Get-Date)" } Get-Date } 並こ 列の 処部 理分 は 276 実行結果 PS C:\> MyWorkflow -PSComputerName tfsv01 2012年6月18日 18:50:58 1 tfsv01 06/18/2012 18:50:58 2 tfsv01 06/18/2012 18:50:58 3 tfsv01 06/18/2012 18:50:58 2012年6月18日 18:50:59 277 並列処理の中のシーケンシャル処理 workflow MyWorkflow { Get-Date parallel{ Echo -InputObject "1 $PSComputerName $(Get-Date)" Start-Sleep -Second 1 Sequence{ Start-Sleep -Second 1 並 Echo -InputObject "2 $PSComputerName $(Get-Date)" 列 Start-Sleep -Second 1 } Echo -InputObject "3 $PSComputerName $(Get-Date)" Start-Sleep -Second 1 } Get-Date } シこ ーの ケ部 ン分 シは ャ ル 278 並列処理の例 リモートコンピューターを一斉にドメインに参加させる Workflow JoinDomain ([string] $Domain) { } Add-Computer -PSComputerName $PSComputerName ‘ -DomainName $Domain –Credential $PSCredential Restart-Computer -PSComputerName $PSComputerName -Wait ` -For PowerShell -Force ワークフローを実行 ComputerName Client01 Client02 Client03 Client04 Client05 PS C:\> $Clients = Import-Csv -Path C:\tools\ps\wf\Clientlist.txt PS C:\> $Cred = Contoso\administrator PS C:\> JoinDomain -Domain CONTOSO -PSComputerName $Clients.ComputerName -PSCredential $Cred 279 foreach -parallel 配列内の各要素に関して同時に実行する ComputerName Client01 Client02 Client03 Client04 Client05 workflow JoinDomain2( [string[]] $ClientList) { $Clients = Import-Csv -Path $ClientList foreach -Parallel ($Client in $Clients.ComputerName) { Add-Computer -PSComputerName $PSComputerName ` -DomainName $Domain –Credential $PSCredential Restart-Computer -PSComputerName $Client -Wait -For Wmi -Force Get-WmiObject -Class Win32_ComputerSystem -PSComputerName $Client Echo -InputObject $Status.Domain } } (注意) 1行ごとに 並列処理 される PS C:\> JoinDomain -Domain CONTOSO -ClientList .\ClientList.txt -PSCredential $Cred 280 お勧めできない並列処理 単一ノードに対して一斉処理を行う (例)1000人のユーザーを並列で作成する ダメな並列処理の例 workflow CreateNewUser([string[]] $IDs) { foreach -parallel($ID in $IDs) { New-ADUser -Name user$ID -PasswordNeverExpires $true } } 281 ワークフロー編 15. ワークフロージョブとデータの永続化 282 ジョブの永続化 何もしなくてもワークフロージョブ(PSWorkflowJob)は永続化される ※ Remove-Job しない限り消えない PS C:\tools\ps\wf> Invoke-Command -Session $S { Get-Job } Id -1 14 15 16 17 18 19 20 Name ---Job1 Job7 Job3 Job1 Job15 Job1 Job1 Job41 PSJobTypeName ------------PSWorkflowJob PSWorkflowJob PSWorkflowJob PSWorkflowJob PSWorkflowJob PSWorkflowJob PSWorkflowJob PSWorkflowJob State ----Running Completed Suspended Completed Stopped Suspended Completed Suspended HasMoreData ----------実行中 True True True True 停止 True True 完了 True True 一時停止 Location -------localhost tfsv01,tfdc02,tf... localhost tfsv03,tfsv01,tf... localhost localhost localhost localhost すべてのジョブを停止して削除する(Stopped にならないと削除できない) Invoke-Command -Session $S { Get-Job | Stop-Job} Invoke-Command -Session $S { Get-Job | Remove-Job } 283 データの永続化(Checkpoint-Workflow) • ワークフローが停止するまでの出力結果を保存する機能 • ごく短時間だが保存時間を要するため使いすぎには注意 Workflow PersistResult { $I =0 Do 変数の値も保存される { $I ++ Echo -Input "$I :: $(get-date)" 実行するたびに結果が永続化(保存)される Checkpoint-Workflow Start-Sleep -second 10 $I ++ Echo -Input "$I ** $(get-date)" Start-Sleep -second 10 } While (-1) } ※ワークフロー実行時に -PSPersist $true を指定すると自動的にすべての出力が永続化される 284 ワークフロージョブのレジューム PS C:\tools\ps\wf> Invoke-Command -Session $s {Resume-Job 2} Id -2 Name ---Job3 PSJobTypeName ------------PSWorkflowJob State ----Suspended HasMoreData ----------True Location -------localhost PS C:\tools\ps\wf> Invoke-Command -Session $s {Get-Job 2} Id -2 Name ---Job3 PSJobTypeName ------------PSWorkflowJob State ----Running HasMoreData ----------True Location -------localhost 285 ワークフローのサスペンド • ワークフローを強制的に一時停止できる • 実行条件に合わないときなどに使用する ※サーバーの再起動時にも自動的にサスペンドされる Suspended 状態に移行 する際に、データは自 動的に永続化される PS C:\tools\ps\wf> Invoke-Command -Session $s {get-job 2} Id -2 Name ---Job3 PSJobTypeName ------------PSWorkflowJob State ----Running HasMoreData ----------True Location -------localhost PS C:\tools\ps\wf> Invoke-Command -Session $s {Suspend-job 2} Id -2 Name ---Job3 PSJobTypeName ------------PSWorkflowJob State ----Suspending HasMoreData ----------True Location -------localhost PS C:\tools\ps\wf> Invoke-Command -Session $s {get-job 2} Id -2 Name ---Job3 PSJobTypeName ------------PSWorkflowJob State ----Suspended HasMoreData ----------True Location -------localhost 286 (例)大量のユーザーを登録するワークフロー Workflow CreateUser { Get-Content -Path \\junichia-vdi\tools\ps\wf\UserList.csv -Encoding String | Out-File -Path .\UserList_Unicode.csv -Encoding unicode $UserList = Import-Csv -Path .\UserList_Unicode.csv foreach ($u in $UserList) { $UserID = $u.userID Echo -InputObject “$(Get-Date) $UserID を作成します" $password = convertto-securestring ` -Input $u.initialpassword -asplaintext -force $Department = $u.Department $FirstName = $u.FirstName $LastName = $u.LastName $HomeDirectory = "\\Home\Share\$userID" InlineScript { New-ADUser ` -Name $using:UserID ` -AccountExpirationDate 2012/12/31 ` -AccountPassword $using:password ` -ChangePasswordAtLogon $using:true ` -Department $using:Department ` -GivenName $using:FirstName ` -Surname $using:LastName ` -HomeDirectory $using:HomeDirectory ` -HomeDrive "Z:" ` -ErrorAction SilentlyContinue ` -ErrorVariable ERRORMESSAGE If ($ERRORMESSAGE.Count -eq 0) { Echo -InputObject “$(Get-Date),$using:UserID を作成しました" } else { Echo -InputObject “$(Get-Date),$using:UserID $ERRORMESSAGE" } } Checkpoint-Workflow } } 287 実行までの流れ PSワークフローセッションを張る $S = New-PSWorkflowSession -ComputerName DC01 ワークフローをDC01上に作成する Invoke-Command -Session $S -FilePath .\CreateNewUser.ps1 ワークフローが作られたことを確認 Domain Controller (DC01) Stopped Invoke-Command -Session $S {Get-Command -CommandType Workflow} PC ロ ー カ ル ワークフローを実行 Invoke-Command -Session $S {CreateUser -PSPersist $true -ErrorAction SilentlyContinue -AsJob} Running DC01 が停電によりシャットダウン DC01 が復電により再起動 もう一度セッションを張る $S = New-PSWorkflowSession -ComputerName DC01 ジョブIDを確認 Invoke-Command -Session $S { Get-Job } ジョブをレジューム Invoke-Command -Session $S { Resume-Job 3 } Suspended Running 288 ワークフロージョブのスケジュール • 条件をトリガーにしてワークフロージョブを起動(Start, Resume) することができる Add-JobTrigger Disable-JobTrigger Disable-ScheduledJob Enable-JobTrigger Enable-ScheduledJob Get-JobTrigger Get-ScheduledJob Get-ScheduledJobOption New-JobTrigger New-ScheduledJobOption Register-ScheduledJob Remove-JobTrigger Set-JobTrigger Set-ScheduledJob Set-ScheduledJobOption Unregister-ScheduledJob 289 Part 5 開発者編 290 Agenda 16. 17. 18. 19. 20. 開発者にとっての Windows PowerShell とは 開発者のための Windows PowerShell 基礎知識 開発者として必要な情報の取得 コマンドレット以外からオブジェクトのインスタンスを作成する Visual Studio(C#)から PowerShell を呼び出す 291 開発者編 16. 開発者にとっての Windows PowerShell とは 292 Question ある開発案件で、Active Directory Domain Service(AD DS) の ユーザー管理アプリを開発することになりました。 AD DS は正直よく知りませんし、Directory Service 用の API を 一から調べるのも面倒です。 293 マイクロソフト製品と PowerShell の関係 • 製品ごとに専用の”コマンドレット”が用意されている • 多くの管理 GUI は裏でコマンドレットを呼んでいる • 各製品への”標準化されたアクセス方法”を提供する Active Directory 管理センター PowerShell コンソール 重要! Exchange 2010 管理コンソール Active Directory PowerShell コマンドレット Exchange Server 用 PowerShell コマンドレット Active Directory Exchange Server 2010 294 PowerShell は開発工数を低減するために存在する • 目的ベースのコマンドレット(CmdLet) • アプリケーションに対する処理の正確性 • ビジネスにとっての高速性 • オペレーション品質と開発品質の向上 • 自動化 • ビジネスに合わせた拡張性 API Active Directory 目的 コマンドレット ユーザーリストを取得 Get-ADUser ユーザーを削除 Remove-ADUser ユーザーを探す Search-ADAccount 295 (例)Active Directory に30日間ログオンしていないユーザー 一覧を取得する Search-ADAccount –AccountInactive –TimeSpan 30 -UsersOnly | ft name たったこれだけ! 296 使えるのは 約 3000 C mdlets .NET Framework Windows Server 2012 R2 リリース時点 297 Windows PowerShell の実行環境 PowerShell スクリプト PowerShell コマンドレット PowerShell エンジン .NET Framework COM Class Library CLR(共通言語ランタイム) Windows 298 .NET Framework と PowerShell の関係 PowerShell コマンド レットから .NET Framework を呼び出す .NET Framework から PowerShell コマンド レットを呼び出す 299 開発者編 17. 開発者のための Windows PowerShell 基礎知識 300 開発者編 18. 開発者として必要な情報の取得 301 オブジェクトのタイプを参照する C:\> $a = [System.Math]::Pow(2,3) C:\> $a.GetType() IsPublic IsSerial Name -------- -------- ---True True Double BaseType -------System.ValueType C:\> ( 1 ).GetType() IsPublic IsSerial Name -------- -------- ---True True Int32 BaseType -------System.ValueType PS C:\Windows\system32> (Get-Service).GetType() IsPublic IsSerial Name -------- -------- ---True True Object[] BaseType -------System.Array 302 メンバー(メソッド、プロパティ)を参照する C:\> Get-Service | Get-Member TypeName: System.ServiceProcess.ServiceController Name ---Name RequiredServices Disposed Close Continue CreateObjRef Dispose Equals ExecuteCommand GetHashCode GetLifetimeService GetType InitializeLifetimeService Pause Refresh Start Stop WaitForStatus CanPauseAndContinue CanShutdown CanStop Container MemberType ---------AliasProperty AliasProperty Event Method Method Method Method Method Method Method Method Method Method Method Method Method Method Method Property Property Property Property クラス名 Definition ---------Name = ServiceName RequiredServices = ServicesDependedOn System.EventHandler Disposed(System.Object, System.EventArgs) System.Void Close() System.Void Continue() System.Runtime.Remoting.ObjRef CreateObjRef(type requestedT... System.Void Dispose() bool Equals(System.Object obj) System.Void ExecuteCommand(int command) int GetHashCode() System.Object GetLifetimeService() type GetType() System.Object InitializeLifetimeService() System.Void Pause() System.Void Refresh() System.Void Start(), System.Void Start(string[] args) System.Void Stop() System.Void WaitForStatus(System.ServiceProcess.ServiceCont... bool CanPauseAndContinue {get;} bool CanShutdown {get;} bool CanStop {get;} System.ComponentModel.IContainer Container {get;} 303 PS > Get-Service | Get-Member -MemberType Method メソッドだけ表示 TypeName: System.ServiceProcess.ServiceController Name ---Close Continue CreateObjRef Dispose Equals ExecuteCommand GetHashCode GetLifetimeService GetType InitializeLifetimeService Pause Refresh Start Stop WaitForStatus MemberType ---------Method Method Method Method Method Method Method Method Method Method Method Method Method Method Method Definition ---------System.Void Close() System.Void Continue() System.Runtime.Remoting.ObjRef CreateObjRef(type requestedType) System.Void Dispose() bool Equals(System.Object obj) System.Void ExecuteCommand(int command) int GetHashCode() System.Object GetLifetimeService() type GetType() System.Object InitializeLifetimeService() System.Void Pause() System.Void Refresh() System.Void Start(), System.Void Start(string[] args) System.Void Stop() System.Void WaitForStatus(System.ServiceProcess.ServiceControl... 304 ロードされているアセンブリ の一覧を参照する PS C:\> [system.AppDomain]::CurrentDomain.GetAssemblies() | out-GridView PS C:\> $M = [system.AppDomain]::CurrentDomain.GetAssemblies() PS C:\> $M | Where-Object { $_.Location } | Foreach { Split-Path -Leaf $_.location} mscorlib.dll PowerShell_ISE.exe Microsoft.PowerShell.ISECommon.dll System.dll System.Windows.Forms.dll System.Drawing.dll System.Management.Automation.dll System.Core.dll Microsoft.PowerShell.GPowerShell.dll System.ComponentModel.Composition.dll Microsoft.PowerShell.Editor.dll PresentationFramework.dll WindowsBase.dll PresentationCore.dll System.Xaml.dll System.Configuration.dll System.Xml.dll System.Runtime.Serialization.dll UIAutomationProvider.dll Accessibility.dll System.Numerics.dll System.Management.dll SMDiagnostics.dll System.DirectoryServices.dll Microsoft.iX.ScriptExplorer.AgentIntegrationSer Microsoft.Management.Infrastructure.dll vice.dll PresentationCore.resources.dll System.Runtime.DurableInstancing.dll PresentationFramework.Aero.dll System.WorkflowServices.dll UIAutomationTypes.dll System.ServiceModel.Discovery.dll System.Configuration.Install.dll System.ServiceModel.Activities.dll System.Transactions.dll System.ServiceModel.Routing.dll Microsoft.PowerShell.Security.dll Microsoft.VisualStudio.Diagnostics.ServiceModel System.Data.dll Sink.dll Microsoft.PowerShell.GraphicalHost.dll System.ServiceModel.Channels.dll mscorlib.resources.dll System.ServiceModel.Web.resources.dll Microsoft.CSharp.dll System.IdentityModel.dll PresentationFramework.resources.dll System.resources.dll System.ServiceProcess.dll Microsoft.PowerShell.Commands.Management.dll Microsoft.PowerShell.Commands.Utility.dll Microsoft.iX.ScriptExplorer.PSISE.dll Microsoft.iX.ScriptExplorer.AgentIntegrationSer vice.Interfaces.dll System.ServiceModel.Web.dll System.ServiceModel.dll 305 開発者編 19.コマンドレット以外からオブジェクトのインスタンスを作成する 306 コマンドレット以外から オブジェクトのインスタンスを作成する方法 • New-Object -ComObject <ProgID> • New-Object -TypeName <Class Name> • [<Class Name>]::<Member()> 307 COM オブジェクトを作成する New-Object -ComObject <ProgID> PS > $IE = New-Object -ComObject InternetExplorer.Application PS > $IE.Navigate2( “http://www.microsoft.com” ) PS > $IE.Visible = $True PS > $ppt = New-Object -ComObject PowerPoint.Application PS > $excel = New-Object -ComObject Excel.Application PS >$worksheet = New-Object -ComObject Excel.Sheet.12 PS >$worksheet.SaveAs( “C:\Tmp\test.xlsx”) 308 ProgID を調べるには OLE Viewer 309 例:指定したURLのページを保存するスクリプト $url = "http://www.microsoft.com/japan/" $code = '$WShell = New-Object -comobject WScript.Shell; ' $code = $code + '$WShell.AppActivate(''Web ページの保存'', $true); ' $code = $code + '$WShell.SendKeys(''%T'') ; ' $code = $code + '$WShell.SendKeys(''{DOWN}'') ; ' ##$code = $code + '$WShell.SendKeys(''{DOWN}'') ; ' $code = $code + '$WShell.SendKeys(''{ENTER}'') ; ' $code = $code + '$WShell.SendKeys(''%N'') ; ' $code = $code + '$WShell.SendKeys(''{HOME}'') ; ' $code = $code + '$WShell.SendKeys(''C:\TMP\'') ; ' $code = $code + '$WShell.SendKeys(''%S'')' $ie = New-Object -ComObject InternetExplorer.Application $ie.Navigate( $url ) while ($ie.ReadyState -ne 4) { Start-Sleep -Milliseconds 100} Start-Process powershell.exe -argument ('-version 2.0 -noprofile -windowstyle hidden -command "{0}"' -f $code) 16 $ie.ExecWB(4,0,$null,[ref ]$null) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 310 例:パフォーマンスデータを Excel シートに 書き込むスクリプト 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 $excel = New-Object -ComObject Excel.Application $Workbook = $Excel.Workbooks.Add() $workbook.Worksheets.Item("sheet1").delete() $workbook.Worksheets.Item("sheet2").delete() $Worksheet = $Workbook.ActiveSheet $Worksheet.Name = "junichia" $worksheet.Range("A1").columnwidth = 20 $cells = $worksheet.Cells $excel.Visible = $True $row = 1 $Cells.Item($row,1) = "Processor Time" $row++ $Cells.Item($row,2) = "CPU1" $Cells.Item($row,3) = "CPU2" $Cells.Item($row,4) = "CPU3" $Cells.Item($row,5) = "CPU4" 21 $Cells.Item($row,6) = "Average“ 22 23 Do 24 { $perf =Get-WmiObject ` 25 -Class win32_perfformatteddata_perfos_processor ` -Property PercentProcessorTime $i = 1 26 $row++ 27 $cells.Item($row,1) = ` 28 (Get-Date -format "yyyy/MM/dd hh:mm:ss").tostring() foreach ($p in $perf ) { 29 $i++ 30 $Cells.Item($row,$i) = $p.PercentProcessorTime 31 If ($p.PercentProcessorTime -ge 20) ` 32 {$Cells.Item($row,$i).Interior.ColorIndex = 3} 33 } 34 Start-Sleep -Seconds 1 35 36 } while (-1) 311 PowerShell から .NET Framework を呼ぶには • インスタンスを持たない静的クラスの場合 [<ClassName>]::<Member(Param)> ※IntelliSense サポート PS C:\> [System.math]::Pow(15,3) 3375 • インスタンスが作成可能なクラスの場合 New-Object <ClassName> PS >$Net = New-Object -TypeName System.Net.WebClient PS >$Net.DownloadFile("http://bing.com/","c:\tools\bing.html") PS >$BING = $Net.DownloadString(“http://bing.com”) 312 静的クラス • • • 静的メンバーのみを含んでいる メソッドやプロパティのリファレンス 新しいオブジェクトを作成することができない PS C:\> [System.math] | Get-Member TypeName: System.RuntimeType 静的クラスは RuntimeType になる PS C:\> [System.Math] | Get-Member -static 正しいメンバーを参照する には -Static を付ける TypeName: System.Math Name ---Abs Acos Asin Atan Atan2 ・・・ MemberType ---------Method Method Method Method Method Definition ---------static System.SByte Abs(System.SByte value), static System.Int16 static double Acos(double d) static double Asin(double d) static double Atan(double d) static double Atan2(double y, double x) 313 静的クラスの例 PS > [System.Environment]::CommandLine "C:\Windows\system32\WindowsPowerShell\v1.0\PowerShell_ISE.exe" PS > [System.Environment]::OSVersion Platform ServicePack -------- ----------Win32NT Service Pack 1 Version ------6.1.7601.65536 VersionString ------------Microsoft Windows NT ... PS >[System.Environment]::HasShutdownStarted False PS > [system.appdomain]::CurrentDomain FriendlyName Id ApplicationDescription BaseDirectory DynamicDirectory RelativeSearchPath SetupInformation ShadowCopyFiles : : : : : : : : PowerShell_ISE.exe 1 C:\Windows\system32\WindowsPowerShell\v1.0\ System.AppDomainSetup False 314 New-Object の利用例 ウィンドウを作成する(リストボックス) 1Remove-Variable x 2Add-Type -AssemblyName "System.Windows.Forms" 3Add-Type -AssemblyName "System.Drawing" 4 5$objForm = New-Object System.Windows.Forms.Form 6$objForm.Text = "リストボックス" 7$objForm.Size = New-Object System.Drawing.Size(300,200) 8$objForm.StartPosition = "CenterScreen" 9 10$OKBtn = New-Object System.windows.Forms.Button 11$OKBtn.Location = New-Object System.Drawing.Size(100,120) 12$OKBtn.Size = New-Object System.Drawing.Size(75,20) 13$OKBtn.Text = "OK" 14 15$objListbox = New-Object System.Windows.Forms.Listbox 16$objListbox.Location = New-Object System.Drawing.Size(15,20) 17$objListbox.Size = New-Object System.Drawing.Size(260,80) 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 1..10 | % { $objListbox.Items.Add(“データ $_") } $OKBtn.Add_Click( { foreach ($objItem in $objListbox.SelectedItems) { $x += $objItem } $objForm.Close() }) $objForm.Controls.Add($OKBtn) $objForm.Controls.Add($objListbox) $objForm.TopMost = $true $R = $objForm.ShowDialog() $x 315 .NET Framework のクラスをロードする アセンブリ名で指定する Add-Type -AssemblyName "System.Windows.Forms" Add-Type -AssemblyName "System.Drawing" 以下の書き方は旧式 [void] [system.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") [void] [system.Reflection.Assembly]::LoadWithPartialName("System.Drawing") DLL ファイル名で指定する Add-Type -Path c:\tmp\hoge.dll 316 どんなときにロードが必要か? 使用したいクラスを含むアセンブリがロードされていない場合 PS > New-Object -TypeName System.Printing.PrintServer New-Object : Cannot find type [System.Printing.PrintServer]: make sure the assembly containing this type i s loaded. At line:1 char:1 + New-Object -TypeName System.Printing.PrintServer + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidType: (:) [New-Object], PSArgumentException + FullyQualifiedErrorId : TypeNotFound,Microsoft.PowerShell.Commands.NewObjectCommand エラー PS > Add-Type -AssemblyName System.Printing PS > New-Object System.Printing.PrintServer Name : \\BANDIT2 SubSystemVersion :0 RestartJobOnPoolEnabled : True RestartJobOnPoolTimeout : 600 MinorVersion :0 MajorVersion :3 EventLog : LogPrintingErrorEvents 317 自分で定義したクラスをロードする $myclass = @" using System; public class hogehoge { public DateTime today(int n) { DateTime dtToday = DateTime.Today; return dtToday; } } "@ Add-Type -TypeDefinition $myclass $obj = New-Object hogehoge $obj.today(1) C#ソースコード (参考)here-string と呼ばれる記法 @” ここに記述した文字列がそのまま維持 される “@ 318 開発者編 20. Visual Studio(C#)から PowerShell を呼び出す 319 完成されたコマンドレットに処理を代行させる PowerShell RunSpace を作成してコマンドレットを実行 C# ソースコード using System; public class hogehoge { public String hogehogehoge { PowerShell 呼び出し 結果を受け取り } PowerShell RunSpace Get-Service Get-Process Move-VM ・ ・ ・ ・ } 320 C# から PowerShell をコールするには • System.Management.Automation.dll を参照追加 ※C:\Program Files (x86)\Reference Assemblies \Microsoft\WindowsPowerShell\v1.0 配下 • 以下を using • using System.Collections.ObjectModel; • • • using System.Management.Automation; using System.Management.Automation.Remoting; using System.Management.Automation.Runspaces; • AddScript() / AddCommand() / AddParameter() メソッドを使用して て PowerShell コマンドレットを指定 • Invoke() で実行 321 PowerShell からプロセス一覧を取得 Get-Process PowerShell powershellInstance = PowerShell.Create(); powershellInstance.AddCommand("Get-Process”) Collection<PSObject> results = powershellInstance.Invoke(); foreach (PSObject result in results) { listBox1.Items.Add( result.Members[“Name”].Value.ToString() ); } 322 PowerShell からプロセス一覧を取得 Get-Process -Name notepad PowerShell powershellInstance = PowerShell.Create(); powershellInstance.AddCommand("Get-Process”) 位置パラメタを指定す powershellInstance.AddArgument(“notepad”); る場合に使用する Collection<PSObject> results = powershellInstance.Invoke(); foreach (PSObject result in results) { listBox1.Items.Add( result.Members[“Name”].Value.ToString() ); } 323 Get-Process -Name MS* | Sort-Object -Property ID -descending PowerShell powershellInstance = PowerShell.Create(); powershellInstance.AddCommand("Get-Process”) powershellInstance.AddParameter(“Name",”MS*”); powershellInstance.AddCommand("Sort-Object"); powershellInstance.AddParameter(“Property","id"); powershellInstance.AddParameter("descending"); 名前付きパラメタを指 定する場合に使用する パイプで接続されたコ マンドレット Collection<PSObject> results = powershellInstance.Invoke(); foreach (PSObject result in results) { listBox1.Items.Add( result.Members[“Name”].Value.ToString() ); } 324 Get-Process -Name MS* | Sort-Object -Property ID -descending PowerShell powershellInstance = PowerShell.Create(); powershellInstance.AddScript("Get-Process -Name MS* | Sort-Object -Property id -descending"); コマンドレットをそのまま書けばよい Collection<PSObject> results = powershellInstance.Invoke(); foreach (PSObject result in results) { listBox1.Items.Add( result.Members[“Name”].Value.ToString() ); } 325 RunSpace を明に指定した例 PowerShell powershellInstance = PowerShell.Create(); Runspace powershellRunSpace = RunspaceFactory.CreateRunspace(); powershellRunSpace.Open(); powershellInstance.Runspace = powershellRunSpace; powershellInstance.AddScript("Get-Process -Name MS* | Sort-Object -Property id -descending"); Collection<PSObject> results = powershellInstance.Invoke(); foreach (PSObject result in results) { listBox1.Items.Add( result.Members[“Name”].Value.ToString() ); } 326 PS1ファイルを呼び出す場合 コマンドの代わりに PS1 ファイルを指定する PowerShell powershellInstance = PowerShell.Create(); powershellInstance.AddScript(“C:\\tmp\\script.ps1"); \ではなく\\ Collection<PSObject> results = powershellInstance.Invoke(); foreach (PSObject result in results) { listBox1.Items.Add( result.Members[“Name”].Value.ToString() ); } 327 RunSpace から PipeLine を明に作成して、AddScript にスクリプトを指定する方法 Runspace runspace = RunspaceFactory.CreateRunspace(); runspace.Open(); Pipeline pipeline = runspace.CreatePipeline(); pipeline.Commands.AddScript("c:\\tmp\\getservice.ps1"); Collection<PSObject> results = pipeline.Invoke(); runspace.Close(); foreach (PSObject result in results) { Console.WriteLine(result.Members["Name"].Value.ToString() ); } ※これはコンソールアプリです 328 PowerShell 側の出力結果に注意 PowerShell 側で加工しすぎると、Visual Studio で扱いづらくなる Get-Process | Format-Table ID, Name, WorkingSet, Handles -AutoSize | OutString -Width 90 見た目は良くなるが 1つのストリームで返されるため、 ループ等によって項目ごとの処理が行いづらい 329 (参考)PowerShell にオブジェクトを渡す Visual Studio 上で作成したデータを PowerShell に渡すことも可能 PowerShell powershellInstance = PowerShell.Create(); ObjectQuery query = new ObjectQuery( "SELECT ProcessID,Name,WorkingSetSize,HandleCount,ParentProcessID FROM Win32_Process"); ManagementObjectSearcher searcher = new ManagementObjectSearcher(query); ManagementObjectCollection objects = searcher.Get(); powershellInstance.AddCommand("Format-Table"); powershellInstance.AddParameter("InputObject", objects); powershellInstance.AddParameter("Property", new string[] { "ProcessID", "Name", "WorkingSetSize", "HandleCount", "ParentProcessID" }); powershellInstance.AddCommand("Out-String"); Collection<PSObject> results = powershellInstance.Invoke(); textBox1.Text = results[0].BaseObject.ToString(); 330 さらに詳しく PowerShell Class http://msdn.microsoft.com/en-us/ library/system.management.automation.powers hell(v=vs.85).aspx 331 332
© Copyright 2024 ExpyDoc