スライド 1

勉強会キット
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