Upload
junichi-anno
View
5.207
Download
1
Embed Size (px)
DESCRIPTION
無償の Hyper-V Server は以下からダウンロードできます!この資料のPPT版もダウンロードできます! http://technet.microsoft.com/ja-jp/windowsserver/jj649374
Citation preview
1
Windows PowerShell 4.0 によるWindows Server 2012 R2 の管理 ~ Hyper-V 編
日本マイクロソフト株式会社エバンジェリスト
安納 順一 Junichi Anno
BLOG http://blogs.technet.com/junichia/
勉強会キット
第一版 2013.12.01
2
はじめにこの勉強会キットでは、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部では細かな技術解説は行っていません。このセクションでは、WindowsPowrShell の細かいテクニックも含め、Windows Server 全般を管理するためのスクリプトを作成するのに必要なテクニックについて解説しています。
3
事前準備
Windows Server
2012 R2(GUI使用サーバー)
Hyper-V Server
2012 R2
本勉強会キットの手順書に沿って学習する場合には、事前に以下の環境を準備してください。なお、ホスト名やIPアドレスは演習中に Windows PowerShell コマンドレットを使用して設定するので、事前設定は必要ありません。
物理マシン 物理マシン
Windows Server
2012 R2
Sysprep済の仮想ハードディスク
いずれの OS も以下よりダウンロードできます(OSがインストールされたVHDファイルもダウンロードできます)
http://technet.microsoft.com/ja-jp/evalcenter/dn205286.aspx
ライブマイグレーションを行う場合には2台の物理サーバーが必要です
第1部で使用
第2部で使用
4
Agenda
第1部 基本的な操作方法
このセクションではインストール直後の OS を、PowerShell のコマンドレットだけを使用して Hyper-V が使用できるように環境設定していきます。
第2部 ライブマイグレーション
このセクションでは、第1部でセットアップした Hyper-V 環境にさらに手を入れてライブマイグレーションが実行できるようにします。
第3部 Windows PowerShell エキスパートを目指す方へ
第1部、第2部では細かな技術解説は行っていません。このセクションでは、Windows PowrShell の細かいテクニックも含め、Windows Server 全般を管理するためのスクリプトを作成するのに必要なテクニックについて解説しています。
5
第1部 基本的な操作を学ぼうこのセクションでは、OS インストール直後の状態から、WindowsPowerShell だけを使用して、Hyper-V 上に仮想マシンを立ち上げます。
6
1台目の Windows Server
1. Windows Server 2012 R2 のインストール
2. Windows PowerShell の基本設定
統合スクリプト環境の起動
実行ポリシーの設定
リモーティングの設定
3. Windows Server の基本設定
IP アドレスの設定
DNS の設定
ローカルコンピューター名の設定
Windows Update の実行
4. 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 の環境設定
7
1.Windows Server 2012 R2 のインストール
① Windows Server 2012 R2 を「GUI付き」で普通にインストールしてください。ここでは Windows PowerShell は使用しません。以降の手順で Windows PowerShell を使用して環境設定を行います。
8
2. Windows PowerShell の基本設定統合スクリプト環境の起動
① Windows Server 2012 R2 にサインインする
② デスクトップのタスクバーに登録されている Windows PowerShell アイコンをクリックして PowerShell コンソールを起動する。
③ 一度コンソールを閉じる
④ Windows PowerShell アイコンを「右クリック」して「ISE を管理者として実行する」を選択し、ISE(統合スクリプト環境)を起動する。
スクリプトエディタ
スクリプト実行画面コマンドレットを直接実行
コマンドレット検索
文字が小さい場合には[Ctrl]+[+] で拡大できます。[Ctrl] + [-] で縮小できます。
9
実行ポリシーの設定
① 以下のコマンドレットを実行し、ローカルで作成したスクリプトは署名なしで実行できるように実行ポリシーを変更する
PS C:¥>Set-ExecutionPolicy RemoteSigned
PS C:¥>Enable-PSRemoting –force
リモーティングの有効化
① 以下のコマンドレットを実行し、PowerShell によるリモート管理を有効にする
10
3. Windows Server の基本設定IP アドレスの設定
① ネットワークアダプタの一覧を表示し、IPアドレスを設定するネットワークカードのInterfaceIndex を特定する
② ターゲットとなるネットワークアダプターの情報を確認する(以下の例ではInterfaceIndex = 13 としている)
③ 既定では 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 を使用する
PS C:¥> Get-NetAdapter | FT Name, InterfaceIndex, InterfaceDescription
PS C:¥> Get-NetIPAddress -InterfaceIndex 13 -AddressFamily IPv4
11
PS C:¥>Set-DnsClientServerAddress -Interface 24 -ServerAddress 192.168.0.1
DNS の設定① DNS サーバーのアドレスを設定する
参考
PS C:¥> Remove-IPAddress -InterfaceIndex 24 -AddressFamily IPv4
IP アドレスの削除
PS C:¥> Set-DnsClientServerAddress -Interface 24 -ResetServerAddress
DNSの設定を削除する
PS C:¥> Set-NetIPInterface -InterfaceIndex 24 -Dhcp Enabled
DHCP を有効にする
※ 複数の DNS サーバーが存在する場合にはカンマで区切って指定する
12
PS C:¥> $Env:ComputerName
ローカルコンピューター名を設定する① 現在のコンピューター名を取得する
② 新しいコンピューター名を設定し、再起動する
PS C:¥> Rename-Computer -NewName “HV01” -Force -Restart
13
Windows Update を実行する
① 以下のコマンドを実行して、Windows Update PowerShell Module をダウンロードする
上記コマンドでダウンロードできない場合には、以下のサイトから Windows UpdatePowerShell Module の最新版をダウンロードしてくださいhttp://gallery.technet.microsoft.com/scriptcenter/2d191bcd-3308-4edd-9de2-88dff796b0bc※「Windows Update PowerShell Modules」で検索すればヒットします
② 以下のコマンドを使用して、ダウンロードした PSWindowsUpdate.zip ファイルを適当な場所に展開する。ここでは C:¥tmp フォルダに展開しています。
③ Dir コマンドで、 PSWindowsUpdate フォルダが作成されていることを確認
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’ )
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")
14
④ 以下のコマンドを実行し、フォルダの中に格納されているすべてのファイルの「ブロック解除」を行う。この操作はファイルのプロパティ画面から「ブロックの解除」を行うのと同様である。
⑤ PowerShell モジュールの格納場所を確認する
⑥ 既定では C:¥Users¥junichia¥Documents¥WindowsPowerShell¥Modules が存在しないので、以下のコマンドで PowerShell モジュールの格納場所を作成する
PS C:¥>$env:PSModulePath
C:¥Users¥Administrator¥Documents¥WindowsPowerShell¥Modules;C:¥windows¥system32¥Wind
owsPowerShell¥v1.0¥Modules¥;C:¥Program Files (x86)¥Microsoft SDKs¥Windows
Azure¥PowerShell¥
PS C:¥> md C:¥Users¥Administrator¥Documents¥WindowsPowerShell¥Modules
PS C:¥>Unblock-File <ファイルの保存先>¥*.*
(例)
PS C:¥>Unblock-File c:¥tmp¥PSWindowsUpdate¥*.*
15
⑦ 以下のコマンドを実行し PSWindowsUpdate フォルダーをC:¥Users¥Administrator¥Documents¥WindowsPowerShell¥Modules 配下に移動する以下の例では PSWindowsUpdate フォルダーは C:¥tmp にあるものとしている
⑧ PSWindowsUpdate モジュールを読み込む
⑨ Windows Update を実行する
PS C:¥> Move C:¥tmp¥PSWindowsUpdate C:¥Users¥Administrator¥Documents
¥WindowsPowerShell¥Modules
PS C:¥> Import-Module PSWindowsUpdate
PS C:¥> Get-WUInstall -AcceptAll
16
4. Hyper-V の構成Hyper-V 役割をインストールする
① 以下のコマンドで現在インストールされている役割と機能の一覧を参照する
② 以下のコマンドを実行して、Hyper-V 役割と管理ツール群をインストールし再起動する
③ Hyper-V 関連のコマンドレットを確認する
PS C:¥> Get-WindowsFeature
PS C:¥> Add-WindowsFeature Hyper-V -IncrudeAllSubFeature -IncludeManagementTools
-Restart
PS C:¥> Get-Command -Module Hyper-V
17
Hyper-V ホストの設定値を変更する
① Hyper-V ホストの規定値を確認する
② 仮想ハードディスクの既定の保存先を設定する※以下の例では仮想ハードディスクの既定の保存先を D:¥VM に指定しています
③ 仮想ハードディスクの構成ファイルの既定の保存先を設定する
PS C:¥> Set-VMHost -VirtualHardDiskPath D:¥VM
PS C:¥> Set-VMHost -VirtualMachinePath D:¥VM
PS C:¥> Get-VMHost | FL
18
Hyper-Vレプリカを有効にする
① Hyper-V レプリカの設定値を確認する
② Hyper-V レプリカを有効にし、認証タイプを Kerberos にする
③ どんなサーバーからの複製も受け入れ、複製の保存先を D:¥VM に設定する
④ Windows Firewall の受信規則を確認する
PS C:¥> Get-VMReplicationServer | FL
PS C:¥> Set-VMReplicationServer -ReplicationEnabled $True
-AllowedAuthenticationType Kerberos
PS C:¥> Set-VMReplicationServer -ReplicationAllowedFromAnyServer $True
-DefaultStorageLocation D:¥VM
PS C:¥> Get-NetFirewallRule -Direction Inbound
19
⑤ Windows Firewall の受信規則の中から、Hyper-V レプリカに関する設定を確認する
※ HTTP と HTTPS に関する規則が存在することがわかります※ それぞれ、ルール名で保存されています
HTTP : VIRT-HVRHHTTPL-In-TCP-NoScopeHTTPS : VIRT-HVRHHTTPSL-In-TCP-NoScope
⑥ “Hyper-V レプリカ HTTP リスナー(TCP受信)”規則を有効にする
PS C:¥> Get-NetFirewallRule -Direction Inbound -Desctiption *レプリカ*
PS C:¥> Set-NetFirewallRule -Name “VIRT-HVRHTTPL-In-TCP-NoScope”
-Enabled True
$ は必要ありません
20
仮想スイッチの作成
① 仮想スイッチの一覧を表示する
※まだ仮想スイッチは存在しません
② ネットワークアダプターの一覧を表示し、外部仮想スイッチにバインドするネットワークアダプターの Name 値を確認する
③ 新しい外部スイッチを “ExternalSwitch” という名前で作成する。以下の例ではバインド先のネットワークアダプタ名は“イーサネット”として指定している。
④ ②で確認したHyper-V ホストの NIC が仮想化され、“ExternalSwitch”に接続されたことを確認する
※ “vEthernet (ExternalSwitch)” という仮想NIC が新たに作成されたことを確認してください
PS C:¥> Get-VMSwitch
PS C:¥> New-VMSwitch -Name “ExternalSwitch” -NetAdapterInterName “イーサネット”
-AllowManagementOS $True
PS C:¥> Get-NetAdapter | FL
PS C:¥> Get-NetAdapter | FL
21
5. DNS サーバーを構成するDNSサーバー役割をインストールする
① DNS をインストールする
② DNS サービス関連のコマンドレットを確認する
DNS ゾーン の確認
① 現在のゾーン設定を確認する
現時点ではゾーンは存在しません。以降の手順でActive Directory ドメインを構築します。
PS C:¥> Add-WindowsFeature dns -IncludeManagementTools
-IncrudeAllSubFeature -Restart
PS C:¥> Get-Command *DNSServer*
PS C:¥> Get-DNSServerZone
22
6. Active Directory ドメインを構成するActive Directory Domain Service (AD DS)役割をインストールする
① AD DS をインストールする
② AD DS 関連のコマンドレットを確認する
Active Directory ドメインを構築する
ここでは Contoso.com ドメインを作成します
① 必要なモジュールをインポートする
② 以下のコマンドを実行して回復モードパスワードを SecureString に変換し、$Password変数に格納する。ここではパスワードを P@ssw0rd としています。
PS C:¥> Add-WindowsFeature AD-Domain-Services -IncludeManagementTools
-IncrudeAllSubFeature -Restart
PS C:¥> Get-Command -module ActiveDirectory
PS C:¥> Import-Module ADDSDeployment
PS C:¥> $Password = ConvertTo-SecureString “P@ssw0rd” -AsPlainText -Force
23
③ ドメインコントローラーに昇格する※ 以下は便宜上改行していますが、実際には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
24
④ Contoso.com ゾーンが作成されていることを確認する
PS C:¥> Get-DNSServerZone -Name contoso.com | FL
25
7. DHCP サーバーを構成するDHCP サービスをインストールする
今後仮想マシンを作成した際にアドレスをリースできるようにするため、DHCPサーバーをセットアップしておきます。
① 以下のコマンドで DHCP サービスをインストールする
※ -Restart パラメタは、再起動が必要な場合に限って再起動が行われます。DHCPサービスのインストールでは再起動は行われません。
② DHCPサービス関連のコマンドレットを確認する
PS C:¥> Add-WindowsFeature DHCP -IncrudeAllSubFeature -IncludeManagementTools
-Restart
PS C:¥> Get-Command *DHCP*
26
DHCP サービスを構成する
① DHCP サーバーのバインディングが 192.168.0.1 に設定されていることを確認する※バインディングが有効にされた NIC を通じて DHCP サービスによる IP アドレスリースが行われます
BindingState が True であることを確認してください。
② DHCP サービスのバインディングを 192.168.0.1 に設定する(設定されていない場合)※事前に Get-NetAdapter で NIC の Name プロパティを確認してください。以下の例で
-InterfaceAlias に指定している値は NIC の Name プロパティです。
③ DHCP サービスを Active Directory で承認する
④ DHCP サービスに必要なセキュリティグループを作成する※Netsh コマンドを使用します
PS C:¥> Get-DHCPServerV4Binding
PS C:¥>Set-DHCPServerV4Binding -InterfaceAlias “vEthernet (ExternalSwitch)”
-BindingState $True
PS C:¥> Add-DHCPServerInDC -DnsName contoso.com
PS C:¥> Netsh dhcp add SecurityGroups
27
⑤ DHCP サービスを再起動
⑥ もしサーバーマネージャー上に「DHCP サーバーの構成が必要です」が表示され続けるようであれば、以下のコマンドを実行してアラートをリセットする
PS C:¥> Restart-Service DHCPServer
PS C:¥> Set-ItemProperty
–Path registry::HKLM¥SOFTWARE¥Microsoft¥ServerManager¥Roles¥12
–Name ConfigurationState –Value 2
28
スコープを作成する
① IPV4 のスコープを追加
② 追加したスコープを表示し、Scope ID を確認する※ この演習では 192.168.0.0 と設定されているはず
③ 作成したスコープに DNS Server を追加する
PS C:¥>Get-DHCPServerV4Scope
PS C:¥> Set-DhcpServerV4ScopeOptionValue -ScopeID 192.168.0.0 -DnsServer 192.168.0.1
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
29
8. 仮想マシンの構成
ゲスト OS の作成
① ゲストOSの一覧を取得する※何も表示されません
② ゲストOS を作成するこの例では VM01 という名前のゲストOSを作成します。仮想マシンの世代は「第一世代」としています。また、仮想ハードディスクの保存先は D:¥VMs¥VM01.vhd です。
PS C:¥> Get-VM
ここでは既に OS がインストールされている仮想ハードディスクを使用して、新しいゲストOSを作成します
PS C:¥> New-VM -Name “VM01”
-MemoryStartupBytes 1024MB
-VHDPath D:¥VMs¥VM01.vhd
-SwitchName “ExternalSwitch”
-Generation 1
-BootDevice IDE
30
③ 作成したゲストOS VM01 の設定値を確認する
④ 動的メモリを有効にし、仮想CPUの割り当て数を 2 に変更する
⑤ ゲストOSを起動する
PS C:¥> Get-VM -Name VM01 | FL
PS C:¥> Set-VM -Name VM01 -ProcessorCount 2 -DynamicMemory
PS C:¥> Start-VM VM01
31
ゲスト 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 コンソールから以下を実行してリモーティングを有効化
• ゲストOS の PowerShell コンソールから ネットワーク探索を有効化
PS C:¥> Enable-PSRemoting -Force
PS C:¥> netsh advfirewall firewall set rule group=”network discovery” new enable=yes
32
ゲスト OS の環境設定を行う
※この操作は Hyper-V ホスト側でおこないます
① ゲストOSをリモート管理するために、Hyper-V ホスト側の TrustedHosts の設定を行う
② ゲストOSに接続するための資格情報を作成する※ここではゲストOSのパスワードが P@ssw0rd であるとします
③ ゲストOSにリースされているIPアドレスを確認する
④ 作成したクレデンシャルを使用して、ゲストOSに接続する※ ゲストOS VM01 には、DHCPサーバーより 192.168.0.11 がリースされているものとします
PS C:¥> Set-Item WSMan:¥localhost¥Client¥TrustedHosts 192.168.0.* -Concatenate
PS C:¥> Get-DhcpServerV4Lease -ScopeId 192.168.0.0
PS C:¥> $Pass = ConvertTo-SecureString “P@ssw0rd” -AsPlainText -Force
PS C:¥> $Cred = New-Object System.Management.Automation.PSCredential $user, $pass
PS C:¥> $User = “Administrator”
PS C:¥> Enter-PSSession 192.168.0.11 -Credential $Cred
33
⑤ ゲストOS のネットワークアダプター情報を確認する(InterfaceIndex を確認してください)※ゲストOSのセッションに接続したまま実行します
⑥ ゲストOS のIPアドレスを確認する(InterfaceIndex = 12 としています)※PrefixOrigin が DHCPであることを確認してください※ゲストOSのセッションに接続したまま実行します
⑦ ゲスト OS の IP アドレスを 192.168.0.100 に設定する※ゲストOSのセッションに接続したまま実行します
このコマンドを実行すると ゲストOSのIPアドレス変更によってセッションが切断されます。これは正しい動作です。自動的に再接続が試みられますが、[Ctrl]+[C] でキャンセルしてください。
[192.168.0.11] :PS C:¥> Get-NetAapter
[192.168.0.11] :PS C:¥> New-NetIPAddress -InterfaceIndex 12 -IPAddress 192.168.0.100
-AddressFamily IPv4 -PrefixLength 24
[192.168.0.11] :PS C:¥> Get-NetIPAddress -InterfaceIndex 12 -AddressFamily IPv4
34
⑧ 再度ゲストOSに接続する
⑨ DNSサーバーの設定を行う※ゲストOSのセッションに接続したまま実行します
⑩ コンピューター名を変更する※ゲストOSのセッションに接続したまま実行します
⑪ セッションを閉じる
[192.168.0.100] :PS C:¥> Rename-Computer -NewName “HV01” -Force -Restart
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:¥>
[192.168.0.100] PS C:¥>Set-DnsClientServerAddress -Interface 12 -ServerAddress 192.168.0.1
[192.168.0.100] :PS C:¥> Exit
PS C:¥>
35
⑫ VM01 を DNS に登録する
⑬ 再度ゲストOSに接続する
PS C:¥> Add-DnsServerResourceRecordA -Name VM01 -IPAddress 192.168.0.100
-ZoneName contoso.com
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:¥>
36
⑫ 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:¥>
37
⑫ 仮想マシン VM01 を再起動する
⑬ 資格情報なしで VM01 に接続できることを確認する
⑭ セッションを閉じる
PS C:¥> Restart-VM VM01 -Force
PS C:¥> Enter-PSSession VM01
[VM01]: PS C:¥>
[VM01]: PS C:¥> Exit
PS C:¥>
38
第2部 ライブマイグレーションこのセクションでは、第1部で作成した環境に Hyper-V サーバーをもう1台加え、ライブマイグレーションが行える環境を構築します。もちろん、各種設定は Windows PowerShell のみで行います。
39
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. ライブマイグレーションの実行
以降の作業ではライブマイグレーションを行うため、Hyper-V がインストールされた2台目の Windows Server が必要となります。ここでは、Hyper-V Server 2012 R2 を使用しています。
40
9. Hyper-V Server 2012 R2 のインストール
2台目の PC を用意し、Hyper-V がインストールされた Windows Server2012 R2 を用意してください。
ここでは Hyper-V Server 2012 R2 を使用します。
Hyper-V Server 2012 R2 をインストールすると自動的に Hyper-V もインストールされます。
41
10. Windows PowerShell の基本設定Hype-V Server 2012 R2 では統合スクリプト環境(ISE)を使用することはできません。
スクリプト環境の起動
① Hyper-V Server 2012 R2 にサインインする
② コマンドプロンプトで以下のコマンドを実行して PowerShell コンソールを起動する。プロンプトが 「PS」に変わったことを確認してください。
実行ポリシーの設定
① 以下のコマンドレットを実行し、ローカルで作成したスクリプトは署名なしで実行できるように実行ポリシーを変更する
リモーティングの有効化
① 以下のコマンドレットを実行し、PowerShell によるリモート管理を有効にする
C:¥> PowerShell
PS C:¥>
PS C:¥>Set-ExecutionPolicy RemoteSigned
PS C:¥>Enable-PSRemoting –force
42
11. Hyper-V Server の基本設定IP アドレスの設定
① ネットワークアダプタの一覧を表示し、IPアドレスを設定するネットワークカードのInterfaceIndex を特定する
② ターゲットとなるネットワークアダプターの情報を確認する(以下の例ではInterfaceIndex = 13 としている)
③ 既定では DHCP を利用するように設定されているので、以下のコマンドを使用して静的なIP アドレスを設定する
PS C:¥>New-NetIPAddress -InterfaceIndex 13 -IPAddress 192.168.0.2
-AddressFamily IPv4 -PrefixLength 24
※ DefaultGateway は必要に応じて※ 既存の静的アドレスを変更する場合には Set-NetIPAddress を使用する
PS C:¥> Get-NetAdapter | FT Name, InterfaceIndex, InterfaceDescription
PS C:¥> Get-NetIPAddress -InterfaceIndex 13 -AddressFamily IPv4
43
PS C:¥>Set-DnsClientServerAddress -Interface 13 -ServerAddress 192.168.0.1
DNS の設定① DNS サーバーのアドレスを設定する
参考
PS C:¥> Remove-IPAddress -InterfaceIndex 24 -AddressFamily IPv4
IP アドレスの削除
PS C:¥> Set-DnsClientServerAddress -Interface 24 -ResetServerAddress
DNSの設定を削除する
PS C:¥> Set-NetIPInterface -InterfaceIndex 24 -Dhcp Enabled
DHCP を有効にする
※ 複数の DNS サーバーが存在する場合にはカンマで区切って指定する
44
ローカルコンピューター名を設定する① 現在のコンピューター名を取得する
② 新しいコンピューター名を設定し、再起動する
③ 再起動後サインインして、再度 PowerShell コンソールを起動する
PS C:¥> $Env:ComputerName
PS C:¥> Rename-Computer -NewName “HV02” -Force -Restart
C:¥> PowerShell
PS C:¥>
45
Hyper-V Server “HV02” を Contoso ドメインに参加させる① ドメインに参加させる
② コンピューターを再起動する
③ 再起動後、ドメインアカウント(contoso¥administrator)でサインインしてください
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
46
Windows Update を実行する
① 以下のコマンドを実行して、Windows Update PowerShell Module をダウンロードする
上記コマンドでダウンロードできない場合には、以下のサイトから Windows UpdatePowerShell Module の最新版をダウンロードしてくださいhttp://gallery.technet.microsoft.com/scriptcenter/2d191bcd-3308-4edd-9de2-88dff796b0bc※「Windows Update PowerShell Modules」で検索すればヒットします
② 以下のコマンドを使用して、ダウンロードした PSWindowsUpdate.zip ファイルを適当な場所に展開する。ここでは C:¥tmp フォルダに展開しています。
③ Dir コマンドで、 PSWindowsUpdate フォルダが作成されていることを確認
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’ )
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")
47
④ 以下のコマンドを実行し、フォルダの中に格納されているすべてのファイルの「ブロック解除」を行う。この操作はファイルのプロパティ画面から「ブロックの解除」を行うのと同様である。
⑤ PowerShell モジュールの格納場所を確認する
⑥ 既定では C:¥Users¥junichia¥Documents¥WindowsPowerShell¥Modules が存在しないので、以下のコマンドで PowerShell モジュールの格納場所を作成する
PS C:¥>$env:PSModulePath
C:¥Users¥Administrator¥Documents¥WindowsPowerShell¥Modules;C:¥windows¥system32¥Wind
owsPowerShell¥v1.0¥Modules¥;C:¥Program Files (x86)¥Microsoft SDKs¥Windows
Azure¥PowerShell¥
PS C:¥> md C:¥Users¥Administrator¥Documents¥WindowsPowerShell¥Modules
PS C:¥>Unblock-File <ファイルの保存先>¥*.*
(例)
PS C:¥>Unblock-File c:¥tmp¥PSWindowsUpdate¥*.*
48
⑦ 以下のコマンドを実行し PSWindowsUpdate フォルダーをC:¥Users¥Administrator¥Documents¥WindowsPowerShell¥Modules 配下に移動する以下の例では PSWindowsUpdate フォルダーは C:¥tmp にあるものとしている
⑧ PSWindowsUpdate モジュールを読み込む
⑨ Windows Update を実行する
PS C:¥> Move C:¥tmp¥PSWindowsUpdate C:¥Users¥Administrator¥Documents
¥WindowsPowerShell¥Modules
PS C:¥> Import-Module PSWindowsUpdate
PS C:¥> Get-WUInstall -AcceptAll
49
12. Hyper-V の構成
Hyper-V Server には既にHyper-Vの役割がインストールされていますが、PowerShell 管理用モジュールはインストールされていません。ここでは管理モジュールをインストールします。
Windows PowerShell 用 Hyper-V モジュールをインストールする
① 以下のコマンドで現在インストールされている役割と機能の一覧を参照する
② 以下のコマンドを実行して、Windows PowerShell 用 Hyper-V モジュールをインストールする
③ Hyper-V 関連のコマンドレットを確認する
PS C:¥> Get-WindowsFeature
PS C:¥> Add-WindowsFeature Hyper-V-PowerShell -IncludeAllSubFeature
PS C:¥> Get-Command -Module Hyper-V
50
Hyper-V ホストの設定値を変更する
① Hyper-V ホストの規定値を確認する
② 仮想ハードディスクの既定の保存先を設定する※以下の例では仮想ハードディスクの既定の保存先を E:¥VM に指定しています
③ 仮想ハードディスクの構成ファイルの既定の保存先を設定する
PS C:¥> Set-VMHost -VirtualHardDiskPath E:¥VM
PS C:¥> Set-VMHost -VirtualMachinePath E:¥VM
PS C:¥> Get-VMHost | FL
51
Hyper-Vレプリカを有効にする
① Hyper-V レプリカの設定値を確認する
② Hyper-V レプリカを有効にし、認証タイプを Kerberos にする
③ どんなサーバーからの複製も受け入れ、複製の保存先を E:¥VM に設定する
④ Windows Firewall の受信規則を確認する
PS C:¥> Get-VMReplicationServer | FL
PS C:¥> Set-VMReplicationServer -ReplicationEnabled $True
-AllowedAuthenticationType Kerberos
PS C:¥> Set-VMReplicationServer -ReplicationAllowedFromAnyServer $True
-DefaultStorageLocation E:¥VM
PS C:¥> Get-NetFirewallRule -Direction Inbound
52
⑤ Windows Firewall の受信規則の中から、Hyper-V レプリカに関する設定を確認する
※ HTTP と HTTPS に関する規則が存在することがわかります※ それぞれ、ルール名で保存されています
HTTP : VIRT-HVRHHTTPL-In-TCP-NoScopeHTTPS : VIRT-HVRHHTTPSL-In-TCP-NoScope
⑥ “Hyper-V レプリカ HTTP リスナー(TCP受信)”規則を有効にする
PS C:¥> Get-NetFirewallRule -Direction Inbound -Desctiption *レプリカ*
PS C:¥> Set-NetFirewallRule -Name “VIRT-HVRHTTPL-In-TCP-NoScope”
-Enabled True
$ は必要ありません
53
仮想スイッチの作成ライブマイグレーションを実行するには、HV01と同じ名前の仮想スイッチを作成しておく必要があります)
① ネットワークアダプターの一覧を表示し、外部仮想スイッチにバインドするネットワークアダプターの Name 値を確認する
② 新しい外部スイッチを “ExternalSwitch” という名前で作成する。以下の例ではバインド先のネットワークアダプタ名は“イーサネット”として指定している。
③ ②で確認したHyper-V ホストの NIC が仮想化され、“ExternalSwitch”に接続されたことを確認する
※ “vEthernet (ExternalSwitch)” という仮想NIC が新たに作成されたことを確認してください
PS C:¥> New-VMSwitch -Name “ExternalSwitch” -NetAdapterInterName “イーサネット”
-AllowManagementOS $True
PS C:¥> Get-NetAdapter | FL
PS C:¥> Get-NetAdapter | FL
54
⑤ 仮想スイッチ ExternalSwitch が作成されたことを確認する
PS C:¥> Get-VMSwitch
55
13.ライブマイグレーションの有効化と実行ここまでの作業で以下のような環境が構築できました。ここからは HV01 と HV02 間でライブマイグレーションを行うための設定をしていきます。ここからの作業は HV01 上の PowerShell ISE から実行します。
Windows Server 2012 R2(GUI使用サーバー)
Hyper-V Server 2012 R2
物理マシン 物理マシン
HV01 192.168.0.1
Windows Server 2012 R2
• Hyper-V• AD DS• DNS• DHCP
HV02 192.168.0.2
• Hyper-V
仮想スイッチ
ExternalSwitch仮想スイッチ
ExternalSwitch
仮想マシン
VM01 192.168.0.3
Active Directory ドメイン Contoso.com
56
ここからの作業は HV01 上から実行します。
Hyper-V ホストのライブマイグレーションを有効にする
① HV01 と HV02 のライブマイグレーションを有効にする
② 任意のネットワークカードを使用してライブマイグレーションを受信できるようにする
③ パフォーマンスオプションを「圧縮」モードに設定する
④ ライブマイグレーションの認証プロトコルを「Kerberos」に設定する
PS C:¥> Enable-VMMigration -ComputerName HV01, HV02
Set-VMHost -ComputerName HV01, HV02 -UseAnyNetworkForMigration $True
Set-VMHost -ComputerName HV01, HV02 -VirtualMachineMigrationAuthenticationType
Kerberos
Set-VMHost -ComputerName HV01, HV02 -VirtualMachineMigrationPerformanceOption
Compression
57
⑤ 同時に移行できる仮想マシンの数を 10 に変更する
移行の対象となる仮想マシンの「プロセッサの互換性」を設定するライブマイグレーションに使用する物理コンピューターが異なるプロセッサバージョンを搭載している場合には、仮想マシンごとに「プロセッサバージョンが異なる物理コンピューターへ移行する」を有効にして置く必要があります。
① 仮想マシンをシャットダウンする
② HV01 上の VM01 の「プロセッサバージョンが異なる物理コンピューターへ移行する」を有効にする
③ 仮想マシンを起動する
PC C:¥> Set-VMHost -ComputerName HV01, HV02 -MaximumVirtualMachineMigrations 10
PS C:¥> Set-VMProcessor -ComputerName HV01 -VMName VM01
-CompatibilityForMigrationEnabled $True
PS C:¥> Stop-VM -ComputerName HV01 -Name VM01
PS C:¥> Start-VM -ComputerName HV01 -Name VM01
58
Kerberos 委任の設定を行う
委任の設定は、ライブマイグレーションを行う全てのコンピューター間で行う必要があります。また、委任を許可する対象となるのは各コンピューターが持つ以下の 2 つのサービスです。
• CIFS
• Microsoft Virtual System Migration Service
Hyper-V over SMB を使用している場合にはファイルサーバーの CIFS も委任の対象となることに注意してください。
今回は、HV01 と HV02 間での委任を許可するように設定します。
HV01 HV02
CIFS
Microsoft Virtual System
Migration Service
CIFS
Microsoft Virtual System
Migration Service
委任
59
① HV01 に HV02 CIFS サービスへの委任を許可する
② HV02 に HV01 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” }
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” }
60
③ HV01 に HV02 Microsoft Virtual System Migration サービスへの委任を許可する
④ HV02 に HV01 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” }
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” }
61
⑤ HV02 を再起動する(再起動が完了するまで待ち合せる)※委任の設定を適用するためにコンピューターを再起動する必要があります
⑥ HV01 を再起動する※HV02の再起動が完了してから実行してください。
コンピューターアカウントに移行先となるストレージへのアクセス権を与える
※ライブマイグレーションはコンピューターアカウントによる処理であるため、移行先のストレージ対してコンピューターアカウントによるフルアクセス権が必要です。
PS C:¥> Restart-Computer -ComputerName HV02 -Wait -Force
PS C:¥> Restart-Computer -Force
62
ライブマイグレーションを実行する
今回は共有ボリュームや共有フォルダを使用しない シェアード ナシング ライブ マイグレーション を実行してみます。
① 仮想マシン VM01 が HV01 上で動作していることを確認
② 仮想マシン VM01 を HV02 に移動する※HV02 上の E:¥VM¥VM01 に仮想ハードディスクごと移動するものとします
統合スクリプト環境上で実行すると、画面上に移行のプログレスバーが表示されます。
③ 仮想マシン VM01 が HV02 上で動作していることを確認する
PS C:¥> Get-VM -ComputerName HV01
PS C:¥> Move-VM -ComputerName HV01 -Name VM01 -DestinationHost HV02
-IncludeStorage -DestinationStoragePath E:¥VM¥VM01
PS C:¥> Get-VM -ComputerName HV01
63
第3部 エキスパートを目指す方へここからは、Hyper-V だけに特化した手法ではなく、Windows PowerShell の基本的なテクニックから、バックグラウンドジョブ、ワークフローなどの高度なテクニックまでを解説します。Visual Studioからの呼び出し方法についても解説しています。
64
第3部 ~ PowerShell エキスパートを目指す方へ
Part1 基礎編
1.Windows PowerShell の位置づけ
2.基本的なコマンドレットと書式の基礎
3.基本的な文法とスクリプトの作り方
4.Tips
Part2 リモーティング編
5.リモーティングの準備と基礎
6.-ComputerNameを使用したリモート操作
7.PS セッションとは
8.コネクションの永続化と再利用可能なPSセッション
9.Windows PowerShell Web Access(PSWA)
Part3 バックグラウンドジョブ
10. バックグラウンドジョブ
Part4 ワークフロー編
11. Windows PowerShell Workflow とは
12. Windows PowerShell Workflow の基礎
13. ワークフロー特有の記述
14. ワークフロージョブとデータの永続化
Part5 開発者編
15. 開発者にとっての Windows PowerShell とは
16. 開発者のための Windows PowerShell 基礎知識
17. 開発者として必要な情報の取得
18. コマンドレット以外からオブジェクトのインスタンスを作成する
19. Visual Studio(C#)から PowerShell を呼び出す
Windows PowerShell には他にもさまざまなテクニックが用意されています。特に、バックグラウンドジョブの概念はシステム管理を行う上で重要です。
65
Part 1 基礎編
66
基礎編1. Windows PowerShell の位置づけ
67
Windows PowerShell の位置づけ
Windows Familiar – インフラエンジニアから見ると• Windows Script(WSH)に変わる管理プラットフォーム• 高機能なスクリプティング機能による自動管理• WinRM を介したリモートサーバー管理
Windows Familiar – 開発者 から見ると• 高機能なクラスライブラリ• コーディング、テスティングの大幅なコスト削減
Non-Windows Familiar から見ると• OMI(Open Management Infrastructure)を実装したリモートサーバー• 手元のプラットフォームからリモート管理が可能• 使い慣れた言語からリモート管理が可能
68
代表的なスクリプト言語
バッチファイル(拡張子 .bat)
VBScript(拡張子 .vbs)
PowerShell(拡張子 .ps1)
Jscript(拡張子 .js)
MS-DOS時代から使われてきたコマンドシェル上のスクリプト。脈々と現代に引き継がれており、利用者が多い。豊富なコマンド群によって支えられており、案外使い出がある。複数のスクリプトを取りまとめる役割としても便利。
Visual Basic のスクリプト版。「Visual」とあるが、Visual ではない。わかりやすい文法と、緩い規則によって根強いファンが多い。亜種として VBA もあるが微妙に文法は異なる。
JavaScript のMS 実装版として、VBScript とともに登場。JavaScript を Microsoft の独自仕様によって拡張することで、汎用性を増している。
いわずと知れた高機能スクリプト言語。.NET Framework が使えると言うメリットから、利用者は爆発的に増殖中。多くの製品がPowerShell用のコマンドレットを提供しており、Windows Script Host は Server Coreのメニュー程度でしかお目にかかれなくなりつつある。
Win
dow
sS
crip
t
今後エンハンスの予定は無い
OSに合わせて継続的なエンハンス
今後エンハンスの予定は無い
69
Windows
.NET Framework
PowerShell スクリプト
exe
bat VBScript JScript
Script Engine
CLR(共通言語ランタイム)
Class Library
スクリプトの実行環境
PowerShell エンジンCOM
cmd/command
Windows Script HostCscript.exe Wscript.exe
COM
70
コマンドシェルの進化と機能の包含
cmd.exe
command.com
高機能
NT
低機能
DOS/Win31 2000
XP/2003Vista/2008
Windows Script Host
PowerShell 上ではbat/vbs/js も実行可能
Win9x/Me
Win7/2008R2
Windows PowerShell
8
100
200
約2300
コマンドレットの数
71
VBScript vs PowerShell
Exchange 2003 (VBScript) Exchange 2007(PowerShell)
メールボックス統計
Set listExchange_Mailboxs = GetObject("winmgmts:{impersonationLevel=impersonate}!¥¥COMPUTERNAME¥ROOT¥MicrosoftExchangeV2").InstancesOf("Exchange_Mailbox")
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
get-mailboxstatistics
–server $servername
データベース管理
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)
move-storagegrouppath
-identity "First Storage
Group"
–log "C:¥newlogPath"
受信者管理
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
enable-mailbox
-identity domain¥FOO
–database "First Storage
Group¥Private MDB"
72
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/
73出典 http://h50146.www5.hp.com/products/software/oe/hpux/developer/column/smh_02/
HP におけるWBEM の実装
74
出典
http://docs.oracle.com/cd/E19455-01/806-
7119/6jg10nqef/index.html
Solaris における WBEM の実装
75
Microsoft の実装
76
History of Microsoft Management Framework
2000年 Windows 2000 に WMI をインプリメント
– 29 WMI プロバイダを含む
– 同時に Windows NT, 98, 95 用の WMI もダウンロード開始(15 WMI プロバイダー)
※どちらかといえば ”プロバイダー” 提供ベンダー向けのテクノロジー
※ Windows ファミリ間の相互運用性に留まる
2005年 WS-Management が DMTF へ提出、承認
2007年 Windows Server 2008 に WS-Management を実装(WinRM)
• HTTP/S を介して他プラットフォームとの接続が可能に
• Windows PowerShell で WinRM を介したリモートサーバー管理が標準手法として取り込まれる
WS-Management とは Web Services
for Management のこと。Windows
Server ではない。
77
Windows Management Framework
http://www.microsoft.com/downloads/
前提条件• Windows PowerShell ISE がインストールされていること• Microsoft .NET Framework 4.0 がインストールされていること
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 ー 標準
78
Windows Management Framework
Windows Management Framework
IT Pro IT DeveloperSolution
Developer
Storage Network DevicesCPU
Windows PowerShell
CIMOM、SMI-S
標準化されたアクセス
標準化されたプロトコル
標準化されたオブジェクトモデル
WS-Management(WinRM)(Web Service for Management) http
他のプラットフォーム
Service
Provider
開発
WS-Man
CIMOM、
SMI-S
SMI-S(Storage Management Initiative - Specification)
誰が作るの?
79
The Open Group Membership 2012/10/5 時点
Platinum - 5
• Capgemini Netherlands
• Hewlett-Packard USA
• IBM USA
• Kingdee Software (China) Co. Ltd China
• Oracle Corporation USAGold – 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
80
Open Management Infrastructure(nanoWBEM)
• オープンソース版 CIM Server
• 軽量 250KB、C で開発されている
Windows PowerShell、その他
Providers : CIMOM,SMI-S
WS-Management(OMI)
Providers : CIMOM,SMI-S
Storage Network DevicesCPUStorage Network DevicesCPU
WS-Management(WinRM)
各種言語
WinRM Client
WinRM Server
OMI Client
OMI Server
81
82
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月)
83
http://www.opengroup.org/
84
マイクロソフト製品と Windows PowerShell の関係
• 製品ごとに専用の”コマンドレット”が用意されている• 多くの管理 GUI は裏でコマンドレットを呼んでいる• インフラ担当者に、各製品への”標準化されたアクセス方法”を提供する
Active Directory
Active Directory
PowerShell Module
Active Directory管理センター
Hyper-V
Hyper-V
PowerShell Module
System Center
Virtual Machine Manager
PowerShellコンソール
85
Windows PowerShell ISE
• Powershell_ise.exe• Windows PowerShell 専用エディタ• IntelliSense に対応
スクリプトエディタ
スクリプト実行画面コマンドレットを直接実行
コマンドレット検索
英語圏の人たちは”アイス”と読むらしい
86
基礎編2. 基本的なコマンドレットと書式の基礎
87
事前準備• コンソールの環境設定
• 簡易編集を有効に
• エクスプローラー(フォルダー)の環境設定• 「拡張子を表示しない」を無効に
• 実行ポリシーの設定※オンプレミスの”署名無しスクリプト”を実行できるようにする
• リモートからの操作を有効にする(リモーティングの有効化)
• 必要に応じて自分専用の初期設定ファイルを作成(規定では存在しない)
PS C:¥>Set-ExecutionPolicy RemoteSigned
PS C:¥>Enable-PSRemoting –force
PS C:¥>notepad $profile
88
実行ポリシーの設定~ Set-ExecutionPolicy
• “管理者として実行” する必要がある
• 実行ポリシー
– Restricted:制限つき (オペレーターモード)(規定値)
• 対話形式のみ
• スクリプトは実行できない
– AllSigned:署名
• スクリプトは、信頼された発行元による署名が必要
– RemoteSigned:リモートの署名
• “インターネットゾーン” のスクリプトは信頼された発行元による署名が必要
– Unrestricted:無制限
• すべてのスクリプトを実行可能
• リモートのスクリプトについては常に警告
– Bypass:バイパス
• 何もブロックされず警告も表示されない
http://technet.microsoft.com/ja-jp/library/dd347628.aspx
“ポリシーの設定”は、規定ではコンピューター全体に影響する。適用範囲を制限するには、Scope も同時に定義する。
89
コマンドレットの構造
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
<操作>-<ターゲット>
(例)
90
コマンドレットとモジュール
• PowerShell の実行単位は「コマンドレット」• コマンドレットはモジュール(Module)によって提供される• モジュールが読み込まれていないとコマンドレットを使用することは
できない(Import-Module <モジュール名>)
Module
CmdLet
CmdLet
CmdLet
CmdLet
Hyper-V
Add-VMDvdDrive
Add-VMFibreChannelHba
Add-VMHardDiskDrive
Add-VMMigrationNetwork
Add-VMNetworkAdapter
Add-VMNetworkAdapterAcl・・・
Microsoft.PowerShell.Management
Add-Computer
Add-Content
Checkpoint-Computer
Clear-Content
Clear-EventLog
Clear-Item
Clear-ItemProperty
Complete-Transaction
構造 規定のモジュール 例
91
モジュールに関するコマンドレット
• 読み込まれているモジュール一覧の取得
• 使用可能なモジュール一覧の取得
• モジュールを読み込む
• 使用可能なモジュールを全て読み込む
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
92
コマンドレット情報を取得する
• 使用可能なコマンドレット一覧を取得する
• “-VM” という文字列を含むコマンドレットの一覧
• 特定のモジュール内のコマンドレット一覧
• コマンドレットの書式
PS C:¥> Get-Command
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
93
コマンドレットにはエイリアスが用意されているものがある
• 入力の簡易化• DOSコマンドやLinux系シェルとの互換性• エイリアスの一覧を取得する
エイリアス
PS C:¥> Get-Alias
94
コマンドレットの戻り値
• コマンドレットの戻り値は“オブジェクト”である• PowerShell はオブジェクトを操作する言語
• 戻り値を「どのように操作できるか」を知っていることが重要• オブジェクトには「メソッド」と「プロパティ」が用意されている
戻り値を直接、”操作”することが可能
Get-Service サービス一覧
オブジェクト
stop()
95
操作メソッド
メソッドプロパティ
プロパティ
もしも”オブジェクト”が自転車だったら...
色
サイズ
型
ブランド
パーツ
ペダルをこいで前に進む
ハンドルを右に切る
ハンドルを左に切る
フロント ブレーキをかける
リア ブレーキをかける
96
メソッドプロパティ
もしも”オブジェクト”が「Windows のサービス」だったら。。。
DisplayName
Status
DependentServices
Stop()
Start()
Pause()
MachineName
Windowsサービス
97
メソッドとプロパティを調べるには
• コマンドレットのメソッドとプロパティを表示
※ COMのメンバーも取得できるNew-Object -com scripting.filesystemobject | Get-Member
• サービスに対して行える操作を取得する
• 仮想マシンに対して行える操作を取得する
<コマンドレット> | get-member
<コマンドレット> | get-member | sort-object Name | format-list
Get-Service | Get-Member
Get-VM | Get-Member
98
TIPS オブジェクトであるということは...
PS C:¥>$a = “abc”
#普通ならば $a は”文字列” になるけれど...
#オブジェクトだからメソッドとプロパティが用意されている
PS C:¥>$a.ToUpper()
PS C:¥>ABC
PS C:¥>$a.ToUpper().Split("B")[0]
PS C:¥>A
99
コマンドからの出力もオブジェクト化される
PS C:¥> (ipconfig)[18].Split(":")[1].Trim()
object
ipconfig の出力結果
の18行目(0から数えて)
IPv4 アドレス . . . . . . . . . . : 192.168.1.100
ipconfig の出力結果からIPアドレスを取りだす
コロンで分割した(0から数えて)2
つ目の値 前後の空白をトリミング
100
PSドライブ
ファイルシステムだけではなく、さまざまなオブジェクトがドライブとしてアクセス可能(CD コマンドで移動可能)
モジュールが読み込まれていないと使えないドライブもある(例)ActiveDirectory
ファイルシステム エイリアス(Alias:) レジストリ(HKLM:、HKCU:) 証明書(Cert:) 環境変数(Env:) 変数(Variable:) WSMAN設定(Wsman:) Active Directory(AD:) IIS(IIS:) Remote Desktop Service(RDS:)
PS C:¥> Get-PSDrive
101
基礎編3. 基本的な文法とスクリプトの作り方
さまざまな使用例から使い方を学びましょう
102
1. 起動中のサービス一覧 パイプライン Where-Object による条件指定
2. 特定のサービスを停止する () でオブジェクトを表現する
3. ネットワーク情報を取得する 出力結果のフォーマット変換
4. ネットワークの設定を変更する5. ローカルコンピューター名を変更する
変数の宣言 変数の遅延展開 Array 値 ハッシュテーブル 環境変数
6. リモートからコンピューター名を変更する※標準コマンドレット or WMI
クレデンシャルの使い方 WMI に必要なアクセス権
7. ドメインに参加させる※標準コマンドレット or WMI
8. 複数のコンピューターをドメインに参加させる スクリプトの継続行 ファイルの入出力方法 ファイルのコード変換
CSV のヘッダー行について 繰り返し処理
9. イベントログを収集する Select-Object により必要な要素のみを取り出す
10. イベントログをバックアップする11. 独自のイベントログを登録する12. 仮想マシンを作成して起動する
スクリプトの引数を定義する 名前付き引数
13. Hyper-V ライブマイグレーションを実行する14. パフォーマンスログを取得する15. 役割と機能をインストールする16. 仮想ドメインコントローラを複製する17. Hyper-V 仮想スイッチを作成する18. リモートコンピューターから機能を一括で削除する19. リモートコンピューターを一括でシャットダウンする20. すべての Hyper-V ホストの仮想マシンを強制的にシャッ
トダウンする21. すべてのHyper-V ホストのライブマイグレーションを有効
化する
103
PS C:¥>get-service | where-object {$_.Status -eq "Running"}
1.起動中のサービス一覧を取得する
パイプ
サービス一覧を出力
object
サービス一覧
オブジェクトの
まま渡される
object
サービス一覧
104
PS > Get-Service | Where-Object Status -EQ "Running" | Select-Object Name,
Servicetype | Sort-Object ServiceType
コマンドレット1 コマンドレット2
入力パラメタ
コマンドレット3
結果 結果
入力パラメタ
• サービスの一覧を取得• Status が Running のみを抽出• Name プロパティとServiceType プロパティを抽出• ServiceType でソート
オブジェクト
パイプラインについて
PS > Get-Service | Where-Object {$_.Status -EQ "Running"} | Select-Object
-Property Name, Servicetype | Sort-Object -Property ServiceType
V3ではこう書ける
105
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
106
TIPS PS 3.0 では書式を簡略化できます
PS C:¥>get-service | where-object {$_.Status -eq "Running"}
PS C:¥>get-service | where-object Status -eq "Running"
V3 ではこう書ける
107
2.特定のサービスを停止する
PS C:¥>(Get-Service -Name WSearch).Stop()
メソッド
Windows Search サービスのインスタンスを取得
object
Windows Search
インスタンスに対してメソッドを実行
PS C:¥>Stop-Service WSerarch
108
TIPS()で括るとオブジェクトを表す
#Dir の出力結果の最初の行から#Nameプロパティだけを取り出す
(dir)[0].Name
#変数を使用すると以下のように書き換えられる
$D = Dir
$D[0].Name
109
3.ネットワーク情報を取得する
PS C:¥> Get-NetAdapter | FL Name, InterfaceIndex, MacAddress
PS C:¥> Get-NetIPAddress -InterfaceIndex 28 -AddressFamily IPv4
ネットワークアダプタの一覧
IP アドレスの取得
Format-List の略
110
TIPS 出力結果のフォーマットを変換
dir | format-table Name,Length
dir | format-list Name,Length
dir | format-wide Name -column 6
dir | out-gridview
111
4.ネットワークの設定を変更する
PS C:¥>New-NetIPAddress -InterfaceIndex 24 -IPAddress 192.168.205.102
-AddressFamily IPv4 -PrefixLength 24 -DefaultGateway 192.168.205.254
PS C:¥> Remove-IPAddress -InterfaceIndex 24 -AddressFamily IPv4
静的なIPV4アドレスを設定する
IP アドレスの削除
PS C:¥>Set-DnsClientServerAddress -Interface 24
-ServerAddress 192.168.205.1, 192.168.205.3
DNS の設定
既存の静的アドレスを変更する場合には Set-NetIPAddress を使用する
PS C:¥> Set-DnsClientServerAddress -Interface 24 -ResetServerAddress
DNSの設定を削除する
PS C:¥> Set-NetIPInterface -InterfaceIndex 24 -Dhcp Enabled
DHCP を有効にする
112
5.ローカルコンピューター名を変更する
PS C:¥> $Env:ComputerName
ローカルコンピューター名の取得
PS C:¥> (Get-WmiObject -Class Win32_ComputerSystem).Name
PS C:¥> $New_ClientName = “New_ClientName”
PS C:¥> $SysInfo = Get-WmiObject -Class Win32_ComputerSystem
PS C:¥> $SysInfo.Rename($New_ClientName)
PS C:¥> Restart-Computer
ローカルコンピューター名の変更
方法1
方法2
C:¥> Rename-Computer -NewName “tfwin8-xx” -Force -Restart
WMI を使用する場合
標準のコマンドレットを使用する場合
113
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
出力結果
114
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 で置き換えが可能
自動変換できない値であればエラーとなる
115
明示的に宣言することも可能
PS > [System.Int32] $A = 1
PS > [System.String] $B = “abc”PS > [System.Array] $C = “今年は”, 2012, “年です”
PS > $A = 987.654
PS > $A
988
PS > $A = “Hello”
Cannot convert value "Hello" to type "System.Int32“
PS > [System.String] $A = “Hello”
明に宣言すると自動変換はできない
Int32 にキャストされる
0: 今年は
1: 20122: 年です
[System.String]
[System.Int32]
[System.String]
116
変数を削除する
PS > [System.Int32] $A = 1
PS > Remove-Variable A
PS > Get-Variable | Remove-Variable
自分で作成した変数を全て削除※削除できないものについてエラーが出る
117
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
ダブルクオーテーションで括った場合は変数は展開される
シングルクオーテーションで括った場合には変数は展開されない
118
TIPS 変数の遅延展開
PS > $Name = “Junichi”
PS > $Message = “Hello $Name”
PS > $Message
Hello Junichi
PS > $Name = “Junichi”
PS > $Message = { “Hello $Name” }
PS > $Name = “Taro”
PS > $Message
Hello $Name
PS > & $Message
Hello Taro
{} で括ると変数は展開されない
Echo の代わりに & を使用
通常
遅延展開
$Message を定義した後で $Name に値を入れていることに注意
この時点で変数は展開される
119
PS > $Message = { Param( $Name ) “Hello $Name” }
PS > & $Message Junichi
Hello Junichi
遅延展開を利用して関数として定義
120
TIPS 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
Array の作り方
空のアレイを作成(あえてしなくてもよい)
値を追加
数値を追加
遅延展開変数を追加
{}で括っているので遅延展開変数
121
Array 値の参照
PS > $Users[3]
Maki
PS > $Users[-1]
PS > $N = 6
PS > & $Users[5]
64
PS > Foreach ($u in $Users) { New-ADUser -Name $u }
PS > $Users[2..4]
PS > ($Users -eq “Kazunori”).Count
PS > $Users -ne “Kazunori”
PS > $Users -like “*M*”
$users から値を取りだしながらユーザーを作成
配列の2番から4番を取りだす
遅延展開変数の入った行を参照
配列の一番最後
Kazunori 以外のものを抽出
kazunori と一致するものがあるかどうかを検査
M が含まれる行を抽出
122
PS > $arrINT = 1,2,3,4,5,6,7,8,9
PS > $arrINT -ge 5
PS > $Users += $arrINT
PS > $Users | Sort-Object $_
PS > $Users = $Users -ne “Kazunori”
PS > [System.Array]::Reverse($Users)
2つの配列を合成
昇順に並べ替えて出力
Kazunori を削除
Users の中の並び順を逆にする
2つの配列を合成
123
空白を文字列で埋める(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
124
TIPS HashTable
PS > $Users = @{}
PS > $Users.0001 = “Junichi”
PS > $Users.”0001” = “Junichi”
PS > $Users.Add( “0001”, “Junichi” )
PS > $Users.Remove(“0001”)
HashTable の作り方注意 Array は ()
キー 1 に 値 Junichi を登録
キー 0001 に 値 Junichi を登録
キー 0001 の行を削除
125
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
CSV ファイルから値を読み込んでHashTable を作成
126
TIPS 環境変数の取得
#環境変数の一覧を取得cd env:
dir
#特定の環境変数を取得$env:computername
$env:username
$env:userdomain
$env:SessionName
127
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
標準のコマンドレットを使用する
128
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
WMI を使用する
Server Client変更
WM
I
129
TIPS クレデンシャルの作成
その1PS C:¥> $Cred = Get-Credential
その2PS C:¥> $user = “administrator “
PS C:¥> $pass = ConvertTo-SecureString "P@ssw0rd“
-AsPlainText -Force
PS C:¥> $Cred = New-Object System.Management.Automation.PSCredential $user, $pass
ポップアップが表示される
130
TIPS WMI Tester
http://technet.microsoft.com/en-us/library/cc782719(v=ws.10)
• WMI への接続性をテストするツール• リモートコンピューターへの接続も
テストできる
131
TIPS 非ドメインメンバーから WMI接続 が拒否される原因と対処
代表的なエラー番号
• 0x800706ba
• 0x80041003
• 0x80070005
代表的な原因• Firewall の設定• アクセス権
132
必要なアクセス権
• Distributed COM Users メンバーであること
• (規定では)システム管理者であること※wmimgmt.msc で変更可能
133
必要な Firewall の設定
• Windows Management Instrumentation のルール
134
7.ドメインに参加させる
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
Server
AD Domain
参加指示 Client Client
Workgroup
Client
標準のコマンドレットを使用する
135
PS C:¥> $Domain = “tf.com”
PS C:¥> $Client = “ClientComputer”
PS C:¥> $Cred = Get-Credential junichia
PS C:¥> $Admin = “tf¥administrator”
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
認証に関する通信を暗号化するこれを指定しないと以下のエラー
“Client connection to WINMGMT
needs to be encrypted for this
operation. Please adjust your
IWbemServices proxy security settings
and retry. ”
1: ドメインに参加
+2: コンピューターアカウントの作成
WMIのクラスを直接使用する
136
8.複数のコンピューターをドメインに参加させる# 各種定数の設定
$Cred = Get-Credential junichia
$Domain = "tf.com"
$Admin = "tf¥administrator"
$Pass = "P@ssword"# いったん、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
}
ServerCSV Client Client
tfwin8-01,192.168.205.101,経理部tfwin8-02,192.168.205.102,営業部・・
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
137
TIPS 行継続
アクサン グラーブ記号 (`) を使用する
copy-item C:¥tmp¥*.txt `
-destination C:¥
こいつ
138
TIPS 入出力方法
#標準出力
Write-Output “Hello”
Echo “Hello”
#標準入力
$InputData = Read-Host
#ファイルに出力
Out-File -filepath C:¥tmp¥list.txt -inputobject
$Record
#ファイルから入力
$file = Get-Content -Path c:¥tmp¥list.txt
$file = type c:¥tmp¥list.txt
#CSVファイルから入力
$file = Import-CSV -Path c:¥test.csv
これを抑えておけば、ひとまずたいていのことはできます
139
TIPS 出力方法の違い
PS C:¥> 1 + 2 + 3
6
PS C:¥> Echo “Windows PowerShell”
Windows PowerShell
PS C:¥> Write-Output 1 + 2 + 3
1
+
2
+
3
PS C:¥> Echo Windows PowerShell
Windows
PowerShell
空白で区切られる
PS C:¥> Windows PowerShell<エラー>
※ Echo は Write-Output のAlias
PS C:¥> “1” + “2” + “3”
123
140
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
141
TIPS Import-CSV でのヘッダーの取り扱いについて
• 規定では、1行目はヘッダーとして扱われる
• ヘッダーが無い場合には -Header パラメタで指定可能• -Header を指定すると1行目はデータとして扱われる
• ヘッダー単位(列単位)で取り出しが可能
ComputerName, IPAddress, Departmenttfwin8-01,192.168.205.101,経理部tfwin8-02,192.168.205.102,営業部・・
$Computers = Import-Csv -Path $OutputFile -Header ComputerName,IPAddress
$Computers.IPAddress
142
TIPS Out-GridView を使用して出力結果をながめる
入力したグリッド形式データを参照するための EXCEL VIEWER 的ツール
Import-CSV -Path $File | Out-GridView
143
TIPS 繰り返し処理1
#ForEach-Object
Get-ADUser -Filter * | ForEach-Object {$_.name}
Get-ADUser -Filter * | ForEach-Object name
#foreach
$Users = Get-ADUser -Filter *
foreach ($user in $Users) { $user.name }
Active Directory ユーザー一覧から name プロパティをリストする
V3
144
TIPS 繰り返し処理2
#1から10までを出力1..10
#1から10 をリダイレクトして出力1..10 | % {echo $_ }
#User1 から User10 を作成1..10 | % {New-ADUser “User$_” }
※ % は foreach のエイリアス
145
TIPS 繰り返し処理3
$i = 0
do
{
Write-Host $i
$i++
}
while ($i -lt 10)
$i = 0
do
{
Write-Host $i
$i++
}
until ($i -ge 10)
146
9.イベントログを収集する
C:¥> Get-EventLog -LogName Security -ComputerName tfdc01 -Newest 10
リモートコンピューターのセキュリティログから、最新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 “*ログオン*”
147
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
148
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
149
10. イベントログをバックアップする
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)
セキュリティイベントログをローカルにバックアップする(EVT形式)
PowerShell は管理者モードで起動してください
150
11.独自のイベントログを登録する
C:¥> New-EventLog -Source "TechFielders" -LogName "TechFielders"
ログファイル名 TechFielders、イベントソース TechFielders を新規に登録する
C:¥> Write-EventLog -LogName TechFielders -Source “TechFielders” -EntryType Information -EventId 5963 -Message “元気出せこの野郎!1,2,3 ダァ!"
TechFielders ログにイベントログを書き込む
151
12. 仮想マシンを作成して起動する
param([string] $VMName = "NA", [int] $CPU = 1, [int] $Mem = 10MB)
echo -InputObject $VMName, $CPU, $Mem
$SwitchName = "Intel(R) 82579LM Gigabit Network Connection - Virtual Switch"
New-VM -BootDevice CD `
-MemoryStartupBytes $Mem `
-Name $VMName `
-SwitchName $SwitchName `
-VHDPath ¥¥junichia-vdi¥$VMName¥$VMName.vhdx
Set-VM -ProcessorCount $CPU -DynamicMemory -Name $VMName
Add-VMNetworkAdapter -VMName $VMName -SwitchName $SwitchName
Start-VM -Name $VMName
1
2
3
4
5
6
7
8
9
10
11
PS C:¥> .¥CreateVirtualMachine.ps1 -VMName “VM01" -Mem 1024mb
CreateVirtualMachine.ps1
152
TIPS 引数を受け取る
Write-Output $args[3]
foreach ( $a in $args )
{
Write-Output $a
}
C:¥> .¥hogehoge.ps1 My name is “Junichi Anno” .
5つの引数
MynameisJunichi Anno.
Junichi Anno
153
TIPS 名前付き引数の使い方
param([string] $UserID = “ID", [string] $Password =“PASS")
Write-Output $userid
Write-Output $Password
引数を所定の名前の変数に格納することで、文法チェック等が行いやすくなる
C:¥> hogehoge.ps1 -userid anno
anno
PASS出力結果
規定値
154
13. Hyper-V ライブマイグレーション
$Source = “HostSV01”
$Dist = “HostSV02”
$VMs = get-vm -ComputerName $Source -Name VM*
foreach ($VMName in $VMs.Name) {
Move-VM -ComputerName $Source -Name $VMName -DestinationHost $Dist
}
Guest
メモリ内データ
¥¥Server¥Share¥xxx.vhdx
構成情報 Guest
Host01 Host01
$Source の中の VM で始まるゲストOSを検索している
155
14. パフォーマンスログを取得する
Do
{
$perf =Get-WmiObject -Class win32_perfformatteddata_perfos_processor `
-Property PercentProcessorTime
foreach ($p in $perf) {
$outrec = "Processor" + $i + ":" + $p.PercentProcessorTime
echo $outrec
}
Start-Sleep -Seconds 1
cls
} while (-1)
1
2
3
4
5
6
7
8
9
10
11
プロセッサー(コア単位)の利用率を1秒に1回取得して表示する
1秒スリープ
画面をクリア
目的のパフォーマンスカウンタ(今回はCPU使用率)が含まれているWMIクラスを指定する
156
TIPS パフォーマンスカウンターの調査方法
パフォーマンスカウンタークラスの一覧を取得するには
win32_perfformatteddata_perfos_processor クラスが持っているカウンターの一覧を取得する
C:¥> Get-CimClass Win32_PerfFormatted* |ft CimClassName
C:¥> Get-CimClass Win32_PerfRaw* |ft CimClassName
C:¥> $PerfMon = Get-CimClass Win32_PerfFormattedData_perfos_processor
C:¥> $PerfMon.CimClassProperties |ft Name
157
15. 役割と機能をインストールする
役割/機能の一覧を取得する
C:¥> Get-WindowsFeature
C:¥> Get-WindowsFeature |Select-Object Name
158
PS C:¥> Add-WindowsFeature -Name User-Interfaces-Infra -IncludeAllSubFeature
-IncludeManagementTools
ServerCore にすべての GUI をインストールする(フルインストール)
PS C:¥> Add-WindowsFeature –Name Server-gui-mgmt-infra -IncludeManagementTools
ServerCore に管理ツールだけをインストールする(MinShell)
159
(参考)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
160
ServerManager モジュールでサポートされているコマンドレット
PS C:¥> Import-Module ServerManagerPS C:¥> Get-Command -Module ServerManagerAlias Add-WindowsFeature servermanagerAlias Remove-WindowsFeature servermanagerFunction Disable-ServerManagerStandardUserRemoting servermanagerFunction Enable-ServerManagerStandardUserRemoting servermanagerCmdlet Get-WindowsFeature servermanagerCmdlet Install-WindowsFeature servermanagerCmdlet Uninstall-WindowsFeature servermanager
161
16. DC を複製するWindows Server 2012 以降では、仮想化されたドメインコントローラーを複製して展開することがでる。
Hyper-Vホスト
DC02 DC03ExportDC01
(pdc)
(条件)• 複製元はPDCエミュレーターであってはならない• 複製元は Clonable Domain Controllers グループのメンバーでなくてはならない• Hyper-V ホストは Windows Server 2012
• DCは Windows Server 2012
VHD Import
Hyper-Vホスト
Hyper-Vホスト
162
$SourceDC = "DC02"
$DistDC = "DC03"
$distPDCEmu = DC01"
$HyperVHost = “ITCAMP-TMP"
Move-ADDirectoryServerOperationMasterRole -Identity $distPDCEmu -OperationMasterRole PDCEmulator
Get-ADComputer $SourceDC | %{Add-ADGroupMember -Identity "Cloneable Domain Controllers" -Members
$_.samAccountName}
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
新しいドメインコンローラーの構成ファイルを作成
PDCエミュレーターを複製元となるDC以外に移動
複製元DCをClonable Domain Controllers グループのメンバーにする
複製元DCをシャットダウン
163
つづき
Get-VM $SourceDC | %{ Export-VM $_ -Path C:¥VMs}
Start-VM -Name $SourceDC
$CFG = (Dir “C:¥VMs¥$SourceDC¥Virtual Machines¥*.xml”).FullName
md E:¥$DistDC
Import-VM -Path "$CFG" -ComputerName $HyperVHost -GenerateNewId -Copy
-VhdDestinationPath E:¥$DistDC
Get-VM $SourceDC |Where-Object {$_.State -EQ "Off"} | Rename-VM -NewName $DistDC
Start-VM $DistDC
複製元DCをエクスポート
複製元DCを起動
エクスポートした仮想マシンをインポート
VMの名前が複製元と同じになってしまうので、変更する。ここでは同じHyper-Vホストを使用しているので、OffになっているほうのDCを変名している。
複製先を起動。起動後自動的にDC間複製が始まる。
164
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
165
18. リモートコンピューターから機能を一括で削除する
Workflow RemoveFOCsWF {
$PCs = Import-Csv -Path pclist.txt -Header "PC","IP"
foreach -Parallel ($pc in $PCs) {
Write-Output -InputObject $pc.pc
Remove-WindowsFeature -ComputerName $pc.pc Failover-Clustering -IncludeManagementTools -
Restart
}
}
RemoveFOCsWF
ワークフローを使用してリモートコンピューターからフェールオーバークラスタリングを削除する
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
・・
166
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
}
}
RestartAllPCsWF
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
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
・・
ワークフローを使用して一斉にシャットダウン
168
21. すべての Hyper-V ホストのマイグレーション設定を有効化
Workflow DisableMigrationWF {
$PCs = Import-Csv -Path c:¥tools¥ps¥HOLSetup¥pclist.txt -Header "PC","IP"
foreach -Parallel ($pc in $PCs) {
##Disable-VMMigration -ComputerName $pc.pc
##Set-VMHost -ComputerName $pc.pc -VirtualMachineMigrationAuthenticationType CredSSP `
-MaximumVirtualMachineMigrations 2 -UseAnyNetworkForMigration $true
Enable-VMMigration -ComputerName $pc.pc
Set-VMHost -ComputerName $pc.pc -VirtualMachineMigrationAuthenticationType Kerberos `
-MaximumVirtualMachineMigrations 2 -UseAnyNetworkForMigration $True
}
}
DisableMigrationWF
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
・・
169
基礎編5. その他の Tips
その他、知っていると便利な使用法について
170
True と False の指定
$True と $False は予約語である
C:¥> $MyNameIsJunichi = $True
C:¥> If ($MyNameIsJunichi -eq $True) {Echo 1}
1
171
日時を取得(Date オブジェクト)
Date
Day
DayOfWeek
DayOfYear
Hour
Kind
Millisecond
Minute
Month
Second
Ticks
TimeOfDay
Year
DateTime Add
AddDays
AddHours
AddMilliseconds
AddMinutes
AddMonths
AddSeconds
AddTicks
AddYears
CompareTo
Equals
GetDateTimeFormats
GetHashCode
GetType
GetTypeCode
IsDaylightSavingTime
Subtract
ToBinary
ToFileTime
ToFileTimeUtc
ToLocalTime
ToLongDateString
ToLongTimeString
ToOADate
ToShortDateString
ToShortTimeString
ToString
ToUniversalTime
プロパティ メソッド
PS C:¥> (Date).Year
2012
PS C:¥> (date).adddays(10)24年 5月 23日 12:49:10
172
unix のあのコマンドは?
ls → get-ChildItem
cp → copy-Object
grep → select-String
sort → sort-Object
man → help
clear → clear-Host
cat → get-Content
kill → stop-Process
tee → tee-Object
tail → get-Content
「アレはあるかな?」と思ったら
Get-Alias <unix 上のコマンド>
エイリアス tail は登録されていないので、自分で登録する必要がある(後述)。
173
Get-Content で Tail を模してみる
## 新しく追加された行を待ち合わせて表示
gc .¥test.txt -wait -tail 0
## テキストファイルの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 | Select-String -Pattern ^a
174
tail を Get-Content の Alias として登録する
Set-Alias tail Get-Content
一時的に使用する(現在のコンソール上でのみ)場合は以下のように入力
永続化するには、以下のようにプロファイルに書き込む
Add-Content $profile "Set-Alias tail get-content" -Force
175
Part 2 リモーティング編
176
Agenda ~リモーティング編
6. リモーティングの基礎7. PS セッション
• セッションと PS セッション• テンポラリ PS セッション
8. 接続の永続化と再利用可能な PS セッション9. Windows PowerShell Web Access
177
リモーティング編6. リモーティングの準備
178
OS
リモーティングを有効にする
• 個々の PC で有効にする
PS C:¥>Enable-PSRemoting –force
Win
RM
Win
do
ws Fire
wall
Listener
受付窓口要求を透過
Win
do
ws M
anag
em
ent
処理を受付
port 5985
179
Enable-PSRemoting とネットワークプロファイルの関係※PowerShell 3.0 の場合
Windows Server 系
ドメイン• ADドメインに参加• DCと通信可能
プライベート• DCと通信不可能• ワークグループ• 自宅、職場
パブリック• インターネット• 公共ネットワーク
Windows Client 系
WinRM 有効
ネットワークのプロファイル
WinRM 有効
WinRM 有効
WinRM 有効
同じサブネットのコンピューターに対してはWinRM 有効
SkipNetworkProfileCheck パラメタを指定して実行すれば同じサブネットのコンピューターに対して有効になる
パブリックプロファイルの Firewall の制限をすべて取り払うには以下のコマンドで
Set-NetFirewallRule -Name “WINRM-HTTP-In-TCP-PUBLIC” -RemoteAddres Any
http://technet.microsoft.com/en-us/library/hh849694.aspx
180
• グループポリシーを使用する
[コンピューターの構成]-[ポリシー]-[管理用テンプレート]-[Windows コンポーネント]└[Windows リモート管理(WinRM)]
WinRM リスナを作成
181
WinRM サービスを自動起動にする
182
Windows Firewall で WinRM の要求を受信する
[コンピューターの構成]-[ポリシー]-[Windows の設定]-[セキュリティの設定]└[セキュリティが強化されたWindowsファイアウォール]
└[セキュリティが強化された Windows ファイアウォール(-------)]└[受信の規則]
183
184
管理できるソースとターゲットを制限する(必要に応じて)
管理用のIPアドレス(ターゲット側)を指定
管理用のIPアドレス(ソース側)を指定
185
リモーティングの設定を確認する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 Name SourceOfValue Value ---- ---- ------------- -----System.String Address * System.String Transport HTTP System.String Port 5985 System.String Hostname System.String Enabled true System.String URLPrefix wsmanSystem.String CertificateThumbprintSystem.String ListeningOn_1038621592 10.168.133.49 System.String ListeningOn_1770022257 127.0.0.1 System.String ListeningOn_1055432771 192.168.205.1 System.String ListeningOn_1414502903 ::1 System.String ListeningOn_894013609 2001:4898:0:fff:0:5e...System.String ListeningOn_1270366863 fe80::5efe:10.168.13...System.String ListeningOn_1565265845 fe80::5efe:192.168.2...System.String ListeningOn_2078661606 fe80::25a7:4656:665e...System.String ListeningOn_1147683958 fe80::fc39:ec3b:d823...
PS WSMan:¥localhost¥Listener¥Listener_1084132640>
Listener 名は環境によって異なります
186
ドメイン外のコンピューターを操作するには操作元の「TrustedHost」リストにターゲットコンピューターを追加する※「ターゲット」を管理対象としてもいいかを明記するってこと
Active Directory ドメインOr ワークグループ
ワークグループ orActive Directory ドメイン
OSCredential で認証
Win
RM
Win
do
ws Fire
wall
Litener
Win
do
ws M
anag
em
ent
Trusted
Hosts
操作元 ターゲット
187
PS C:¥> Get-Item wsman:¥localhost¥Client¥TrustedHosts
WSManConfig: Microsoft.WSMan.Management¥WSMan::localhost¥Client
Type Name SourceOfValue Value ---- ---- ------------- -----System.String TrustedHosts
PS C:¥> Set-Item wsman:¥localhost¥Client¥TrustedHosts 192.168.205.* -Concatenate
WSManConfig: Microsoft.WSMan.Management¥WSMan::localhost¥Client
Type Name SourceOfValue Value ---- ---- ------------- -----System.String TrustedHosts 192.168.205.*
規定では未設定
188
TIPS:NIC のプロファイルが「識別されていない」場合
識別されていない = “パブリックネットワーク” である
• ターゲットが Windows クライアント(Windows 7/8 等)であれば、ターゲット PC で以下を実行(Server の場合には行う必要なし)
Enable-PSRemoting -Force -SkipNetworkProfileCheck
189
リモーティング編7. -ComputerName パラメタの利用
190
リモートコンピュータの操作する3つの方法
<コマンドレット> -ComputerName パラメタ
※ -ComputerName では PSセッションは張られない• リモートコンピューターに対して「リモート」から操作を行う• 複数のコンピュータを指定可能
Enter-PSSession -ComputerName ・・・・・
• 対話モード(SSH のような使い方)• Exit コマンドで接続を切断し、セッション消滅
Invoke-Command -ComputerName ・・・・・• -ComputerName パラメタをもたないコマンドレットに対応• リモートコンピューターの「中」で処理を行う• 複数のコンピュータを指定可能• コマンドやスクリプトの終了と同時にセッションと接続は消滅
191
-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
(ほんの一部)
192
-ComputerName の利用
PS C:¥> Get-EventLog -ComputerName tfdc02 -LogName Security -Newest 10
リモートコンピューターのイベントログを取得する
PS C:¥> Restart-Computer -ComputerName tfsv02
リモートコンピューターを再起動する
PS C:¥> get-WindowsFeature -ComputerName tfsv02
リモートコンピューターにインストールされている役割/機能の一覧
PS C:¥> Add-WindowsFeature -ComputerName tfsv02 -Name RSAT-Hyper-V-Tools
-IncludeAllSubFeature -IncludeManagementTools
リモートコンピューターに Hyper-V 管理ツールをインストールする
193
リモーティング編8. PS セッション
194
リモートコンピュータの操作する 3 つの方法
<コマンドレット> -ComputerName パラメタ
※ -ComputerName では PSセッションは張られない• リモートコンピューターに対して「リモート」から操作を行う• 複数のコンピュータを指定可能
Enter-PSSession -ComputerName ・・・・・
• 対話モード(SSH のような使い方)• Exit コマンドで接続を切断し、セッション消滅
Invoke-Command -ComputerName ・・・・・• -ComputerName パラメタをもたないコマンドレットに対応• リモートコンピューターの「中」で処理を行う• 複数のコンピュータを指定可能• コマンドやスクリプトの終了と同時にセッションと接続は消滅
195
“セッション” と “PS セッション”
Local Computer
セッション
セッション
セッション
Remote Computer
PSセッション
PSセッションRemote Computer
PSセッション
PSセッションPSセッション
•PowerShell.exe が起動すると作られる。•コンソールを閉じたらクリア。•個々のセッションは独立
• ユーザー自身が作成し、管理と制御が可能• 永続化が可能• 個々のPSセッションは独立
• Windows PowerShell の実行環境
CALL
CALL
CALL
CALL
196
PS セッション
Source Targetコネクション
• PS セッション内でコマンドやスクリプトが実行される• 変数もセッション内に保存される• コネクションが「消滅」するとセッションも「消滅」する
• テンポラリ PS セッション• -ComputerName を使用したときに作成されるセッション• コマンドが終了するとセッションも終了する
• リユーザブル(Re-usable) PS セッション• コマンド終了後もコネクションを維持し、セッションを継続• 実行中の変数等もそのまま維持される
セッション
197
Invoke-Command の特徴• -ComputerName パラメタを持つ
• どんなコマンドでもリモートで実行可能• -ComputerName パラメタを持たないコマンドレット
(Start-Service, Stop-Service など)• 従来の DOS コマンド(netstat や gpupdate など)
• -Credential のサポート• コマンドレットの中には -Credential を持たないものが多い
• -FilePath パラメタにスクリプトを指定可能• スクリプトはローカルに存在していれば OK
※ただしコマンドレットはリモートに必要
• 複数のコンピューターを指定可能
198
Invoke-Command の利用コマンドやスクリプトをリモートコンピューターに投げて、結果を受け取る
PS C:¥> Invoke-Command -ComputerName tfsv02 -ScriptBlock{ Get-Service }
リモートコンピューターのサービス一覧を取得する
PS C:¥>Invoke-Command -ComputerName tfsv02 -ScriptBlock{ Stop-Service -Name
wuauserv }
リモートコンピューターの Windows Update サービスを停止する
PS C:¥>Invoke-Command -ComputerName tfsv02 -ScriptBlock{ GPUpdate.exe }
リモートコンピューターで GPUpdate を実行する
PS C:¥> Invoke-Command -ComputerName tfsv02 -ScriptBlock{ cd env: ; dir }
リモートコンピューターの環境変数一覧を取得する
Get-Service -ComputerName と同じ
199
Invoke-Command -FilePath パラメタについて
-FilePathパラメタに指定するスクリプト(.ps1)は、ローカルのパス
Invoke-Command -ComputerName SV01 -FilePath .¥hogehoge.ps1
Invoke-Command -ComputerName SV01 -ScriptBlock {.¥hogehoge.ps1}
Target
Computer
hogehoge.ps1
Get-Service・・
スクリプトの中身がリモートに送られる
Target
Computer
hogehoge.ps1
ターゲットに存在しないとエラー
200
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
リモートコンピューター上に仮想マシンを作成し起動する
PS C:¥> Invoke-Command -ComputerName "junichia-demo05"
-FilePath ".¥CreateVirtualMachine.ps1" -ArgumentList “Guest99",“2",“1024MB"
CreateVirtualMachine.ps1
201
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” }
202
複数のリモートコンピューターに対する一括操作
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 |Sort-
Object PSComupterName, Name | Select-Object PSComputerName, Name,
Status} | FT
• 複数のコンピューターに対して処理を行い、結果をマージして出力• 非同期に処理が開始され、全ての処理が終了するまで待ち合わせる
(シーケンシャルでないことに注意!)• 規定では最大同時32台
-ComuterName パラメタに複数のコンピューターを指定する
MachineName と PSComputerName に注意!
203
$PSComputerName
Get-Service -ComputerName TARGET
Invoke-Command -ComputerName TARGET { Get-Service }
Source Targetコマンド
WM
I
実行空間
結果
Source Target
実行空間
WM
I結果
Get-Service コマンドレットの結果にはコンピューター名(MachineName)が含まれる。
Get-Service コマンドレットの結果に含まれるMachineNameにはローカルコンピューター「.」が含まれる。Target コンピューター名を取得するには $PSComputerName を使用する。
PSSession のターゲットとなったコンピューター名が格納される変数
204
CSVファイルから複数コンピューターを入力
Invoke-Command -ComputerName (Import-CSV computerlist.txt).HostName {get-
culture}
LCID Name DisplayName PSComputerName---- ---- ----------- --------------1041 ja-JP 日u本語e (日u本) tfdc011041 ja-JP 日u本語e (日u本) tfdc021042 ja-JP 日u本語e (日u本) tfsv021041 ja-JP 日u本語e (日u本) tfsv01
HostName,IPAddress
tfdc01,192.168.1.1
tfdc02,192.168.1.2
tfsv01,192.168.1.3
tfsv02,192.168.1.4
205
Enter-PSSession• テンポラリ接続により対話型のセッションを開設する• 複数のコマンドを実行可能• 接続が生きている間はセッションも行き続ける
PS> Enter-PSSession -ComputerName Server1
[Server1]: PS > $A = 1
[Server1]: PS > $B = 2
[Server1]: PS > $C = $A + $B
PS> Exit-PSSession
206
リモーティング編9. コネクションの永続化と PS セッションの再利用
207
リユーザブルな PS セッションを使用するには
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
• セッションの作成 :New-PSSession• セッションの削除 :Remove-PSSession• セッション一覧 :Get-PSSession• セッションへの接続 :Connect-PSSession
セッションを作成
セッション内で実行される
208
複数ターゲットを含んだコネクションも可能
PS > $S = New-PSSession -ComputerName CL01,CL02
PS > $S
Id Name ComputerName State ConfigurationName Availability-- ---- ------------ ----- ----------------- ------------80 Session80 tfdc01 Opened Microsoft.PowerShell Available81 Session81 tfdc02 Opened Microsoft.PowerShell Available
PS > Invoke-Command -Session $S {Get-Culture}
Target1コネクション セッ
ション
Target2セッ
ション
Source
209
ローカル変数を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
210
PS セッション情報の取得 ~ Get-PSSession
Target1コネクション セッ
ション
Source1
Source2
PS C:¥tools¥ps> Get-PSSession -ComputerName Target1
Id Name ComputerName State ConfigurationName Availability-- ---- ------------ ----- ----------------- ------------65 tfdc01_Session target1 Opened Microsoft.PowerShell Available80 Session80 taeget1 Opened Microsoft.PowerShell Available
109 Session109 target1 Opened Microsoft.PowerShell Available
• リユーザブルなセッション情報は他のコンピューターからも参照できる• 他のユーザーが作成したセッションは、Credential が有効であれば参照可能
-Credential パラメタを使用可能
211
PS セッションへの再接続
Target1
セッション
Source1
Source2
• リユーザーブルな PS セッションには他のコンピューターから再接続が可能• State=Disconnected, Availability=None に対してのみ
• Disconnect-PSSession コマンドレットで明に Disconnect した場合• ネットワークの切断や PC のハングアップ等で Disconnected になった場合※ コンソールを明に落とした場合は強制終了したものとみなされる
• 同時に2台以上のコンピューターからは接続できない
State=Disconnected
Availability=None
再接続可能
Disconnect-PSSession
Connect-PSSession
212
PS > $S = New-PSSession -ComputerName Target1
PS > $Result = Invoke-Command -Session $S {Get-Service}
PS > Disconnect-PSSession -Session $S
Id Name ComputerName State ConfigurationName Availability-- ---- ------------ ----- ----------------- ------------121 Session121 Target1 Disconnected Microsoft.PowerShell None
Target
PC1
PC
2
PS > Get-PSSession -ComputerName Target1
Id Name ComputerName State ConfigurationName Availability
-- ---- ------------ ----- ----------------- ------------10 Session112 tfdc01 Disconnected Microsoft.PowerShell Busy12 Session121 tfdc01 Disconnected Microsoft.PowerShell None
PS > $S = Get-PSSession -Name Session121 -ComputerName Target1
PS > Connect-PSSession -Session $S
213
State と Availability
Availability
StateOpened 自分自身が接続している
Disconnected 自分自身は接続していない
誰も接続していない
他の誰かが接続してる
自分が接続している
None
Busy
Available
この組み合
わせならば
再接続可能
Id Name ComputerName State ConfigurationName Availability-- ---- ------------ ----- ----------------- ------------
10 Session112 tfdc01 Disconnected Microsoft.PowerShell Busy12 Session121 tfdc01 Disconnected Microsoft.PowerShell None
214
もしソース PC がダウンしたら
ソースが死んでもセッション情報はターゲットに残されている...ただし...
Id Name ComputerName State ConfigurationName Availability-- ---- ------------ ----- ----------------- ------------10 Session112 tfdc01 Disconnected Microsoft.PowerShell Busy
Availability が Busy なので、再接続できない
2
分後
Id Name ComputerName State ConfigurationName Availability-- ---- ------------ ----- ----------------- ------------10 Session112 tfdc01 Disconnected Microsoft.PowerShell None
再接続可能!
215
PS セッションの有効期間
• PS セッションのターゲットの再起動、シャットダウン• Remove-PSSession を実行するまで
• セッションがアイドルタイムアウトするまで• Disconnect してからの時間
PS > Remove-PSSession -Session $S
PS C:¥> Get-PSSessionConfiguration | ft name,idletimeoutms,maxidletimeoutms
Name IdleTimeoutms MaxIdleTimeoutms---- ------------- ----------------microsoft.powershell 7200000 2147483647microsoft.powershell.workflow 7200000 2147483647microsoft.powershell32 7200000 2147483647microsoft.windows.servermanagerworkflows 180000 180000
2時間 596時間
規定値
216
アイドルタイムアウト値の変更
PS C:¥> $SessionOption = New-PSSessionOption -IdleTimeOutMSec 60000
PS C:¥> $S = New-PSSession -ComputerName Target1 -SessionOption $SessionOption
設定方法• 構成ファイルを変更
• Register-PSSessionConfiguration -TransportOption <$TransportOption>
• Set-PSSessionConfiguration -TransportOption <$TransportOption>• PS セッション作成時(特定のセッションのみ)
• New-PSSession -SessionOption <$SessionOption>• コマンド実行開始時(特定のセッションのみ)
• Invoke-Command -SessionOption <$SessionOption>• PS セッション切断時(特定のセッションのみ)
• Disconnect-PSSession -IdeleTimeOutSec <秒>
217
出力バッファモード
出力バッファがFULLになった場合の対応モード• Block : バッファがClearされるまでコマンドの実行をサスペンドする• Drop:コマンドの実行は続けるが古い出力結果から捨てられる
現在のモードを調べる
PS C¥> Get-PSSessionConfiguration | ft Name, OutputBufferingModeName OutputBufferingMode---- -------------------microsoft.powershell Blockmicrosoft.powershell.workflow Blockmicrosoft.powershell32 Blockmicrosoft.windows.servermanagerworkflows Block
「現在の PS セッションでは Drop モードで実行する」を設定
PS C:¥> $o = New-PSSessionOption -OutputBufferingMode Drop
PS C:¥> New-PSSession -SessionOption $o
218
Source2 再接続可能
ループバック PS セッション• LOCALHOST に対してリユーザーブルな PS セッションを作成すれば、
切断したあと別のマシンから再接続が可能• 管理者モードで実行する必要がある
PS > $S = Get-PSSession -ComputerName localhost -Name Backup
PS > Receive-PSSession -Session $S
PS > Remove-PSSession -Session $S
Source1
/Target
セッショ
ンConnect-PSSession
PS> $S = New-PSSession -Name Backup
PS> Invoke-Command -Session $S -FilePath backup.ps1 -AsJob
PS> Disconnect-PSSession -Session $S
219
モジュールとコマンドのインポート• リモートコンピューター上のコマンドレットを一時的に取り込むことができる• “Invoke-Command -Session” を使用する必要が無くなる• コマンドの実行中はセッションを生かしておく必要がある
PS C:> $s = New-PSSession -ComputerName Server1
PS C:> Import-PSSession -Session $s -Module HYPER-V
PS C:¥> Get-VM |ft name
Name
----
VM01
VM02
VM03
VM04
VM05Windows Server
w/ Hyper-V
PS Session
Hyper-V Module
220
リモーティング編10. PSWA
221
Windows PowerShell Web Access
再接続
WS-Man に接続するためのゲートウェイ
IntranetDMZInternet
Home
222
PowerShell Web Access のセットアップ
1.サーバーマネージャーから PowerShell Web Access をインストールする
223
2.IIS で自己署名証明書を作成してバインドを設定する(SSLを有効に)
ご自身のサーバーを指定してください
バインドの設定で作成した証明書を選択
224
2.PowerShell を管理者モードで起動3.以下のコマンドを実行
PS C:¥> Set-ExecutionPolicy RemoteSignedPS C:¥> Import-Module PowerShellWebAccessPS C:¥> Install-PswaWebApplication -webSiteName "Default Web Site" PS C:¥> Add-PswaAuthorizationRule * * *
4.https://<サーバー名>/pswa にアクセス
ここで指定するサーバーは、ターゲットとなるサーバー
225
Part 3 バックグラウンドジョブ編
226
• Windows PowerShell 2.0 よりサポート
• 長時間を要するコマンドレットを非同期に実行し、次の処理に移る
(例)get-eventlog “Security”
• ジョブの有効範囲は現在のセッション
• ジョブを生成するには– -AsJob パラメタ
• 一部のコマンドのみが実装
• ワークフローコマンドには使用可能
– Start-Job コマンドレット
• すべてのコマンド、スクリプトをジョブ化可能
• ジョブの結果がどこに保存されるのかを意識することが重要!
バックグラウンドジョブ
227
-AsJob
-AsJob パラメタを持つコマンドレットは少ない
PS C:¥> Get-Command -ParameterName asjob
CommandType Name ModuleName----------- ---- ----------Function Get-SMCounterSample ServerManagerTasksFunction Get-SMPerformanceCollector ServerManagerTasksFunction Get-SMServerBpaResult ServerManagerTasksFunction Get-SMServerClusterName ServerManagerTasksFunction Get-SMServerEvent ServerManagerTasksFunction Get-SMServerFeature ServerManagerTasksFunction Get-SMServerInventory ServerManagerTasksFunction Get-SMServerService ServerManagerTasksFunction Remove-SMServerPerformanceLog ServerManagerTasksFunction Start-SMPerformanceCollector ServerManagerTasksFunction Stop-SMPerformanceCollector ServerManagerTasksCmdlet Get-WmiObject Microsoft.PowerShell.ManagementCmdlet Invoke-Command Microsoft.PowerShell.CoreCmdlet Invoke-WmiMethod Microsoft.PowerShell.ManagementCmdlet Remove-WmiObject Microsoft.PowerShell.ManagementCmdlet Restart-Computer Microsoft.PowerShell.ManagementCmdlet Set-WmiInstance Microsoft.PowerShell.ManagementCmdlet Stop-Computer Microsoft.PowerShell.ManagementCmdlet Test-Connection Microsoft.PowerShell.Management
※AsJobパラメタを持つコマンド一覧
228
ジョブ関連のコマンドレット
Get-Job バックグラウンドジョブを取得
Receive-Job バックグラウンドジョブの出力結果を取得
Remove-Job バックグラウンドジョブを削除
Start-Job バックグラウンドジョブを開始
Stop-Job バックグラウンドジョブを停止
Wait-Job バックグラウンドジョブが終了するまで待つ
229
バックグラウンドジョブの基本操作
(例)
PS C:¥> $job = start-job -scriptblock {do {$a = 0; echo (date) ; start-sleep 5} while ($a -eq 0) }
PS C:¥> $job
Id Name State HasMoreData Location Command -- ---- ----- ----------- -------- -------6 Job6 Completed True localhost get-eventlog "Windows ...
PS C:¥> Receive-Job $job -Keep
PS C:¥> Stop-Job $job
PS C:¥> Remove-job $job
書式start-job -scriptblock { <スクリプトブロック> }
出力結果が存在する
規定では、出力結果は一度取得するとクリアされてしまうので、-Keep によって残すように指定
5秒に1回日時を表示するジョブ
ジョブを停止
ジョブを削除
230
スクリプトをバックグラウンドジョブ化するには
$flg = $true
$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 }
Start-Sleep -Seconds 1
$index_old = $index.Index
} While ($flg)
まずはスクリプトを作成する(イベントログを取得するスクリプト)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
WatchNewEventLog.ps1
結果を Index をキーとして昇順に並べる
231
##作成したスクリプトをバックグラウンドで実行する
PS C:¥> Start-Job -FilePath .¥WatchNewEventLog.ps1 -Name WatchNewEventLog
Id Name PSJobTypeName State HasMoreData Location Command -- ---- ------------- ----- ----------- -------- -------4 WatchNewEven... BackgroundJob Running True localhost $flg = $true...
## 以下のコマンドで現在までの結果を収集する
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
以下のコマンドで新しいイベントを書き込むC:¥> Write-EventLog -LogName TechFielders -Message "Hello" -Source "TechFielders" -EventId 5963
232
Target
“ジョブの実行場所”と”結果の保存場所”は一緒の法則
Source
Session
• “コマンドの実行場所”と”ジョブの実行場所”は異なる可能性がある• 操作のターゲットがリモートコンピューターであっても、
ジョブがローカルならば結果もローカルに保存される
Cm
dLe
t
Job
/Resu
lt
TargetSource
Session
Cm
dLe
t
Job
/Resu
ltコマンドはリモートジョブはローカル
コマンドはリモートジョブもリモート
233
セッションの永続化とジョブの実行結果
PS> Invoke-Command -Session $S -FilePath backup.ps1 -AsJob
Id Name PSJobTypeName State HasMoreData Location Command -- ---- ------------- ----- ----------- -------- -------2 Job2 RemoteJob Completed True tfdc01 get-service
PS> Receive-Job -Id 2
SRC Target実行
結果
(例1)Invoke-Command -AsJob を使用した場合
セッションに再接続する場合には、結果もリモートに保存しなければ意味がない!!
Invoke-Command をバックグラウンドジョブ化するためのオプション。
スクリプトはリモートだが、ジョブはローカル。Invoke-Command の結果はローカルに保存されることに注意!!!つまりローカルセッションが消えたらジョブの結果も消えるということ!!
234
PS> $S = New-PSSession -ComputerName Target -Name Backup
PS> $Script = “.¥testscript.ps1"
PS> Invoke-Command -Session $S { Start-Job -FilePath $Script }
Id Name PSJobTypeName State HasMoreData Location Command -- ---- ------------- ----- ----------- -------- -------1 Job1 BackgroundJob Running True localhost backup...
PS> Disconnect-PSSession -Session $S
SRC1 Target実行
結果
(例2)Invoke-Command {Start-Job} を使用した場合
(つづく)
SRC2
スクリプトをジョブ化することで、結果がリモートに保存されるため、セッションを永続化すれば別のコンピューターから取り出せる。
235
PS> Get-PSSession -ComputerName tfdc01
Id Name ComputerName State ConfigurationName Availability-- ---- ------------ ----- ----------------- -------------1 backup tfdc01 Disconnected Microsoft.PowerShell None
PS> $S = Connect-PSSession -Name backup -ComputerName tfdc01
PS> Invoke-Command -Session $S { Get-Job }
Id Name PSJobTypeName State HasMoreData Location-- ---- ------------- ----- ----------- --------1 Job1 BackgroundJob Completed True localhost
PS> Invoke-Command -Session $S {Receive-Job -Id 1}
別のコンピューターから接続して結果を取得
236
バックグラウンドジョブのスケジューリング
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
• PSScheduledJob モジュールで提供
237
ジョブスケジューリングの例$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
}
タスクマネージャーで参照可能
238
Part 4 ワークフロー編
239
Agenda ~ワークフロー編
11.Windows PowerShell Workflow とは12.Windows PowerShell Workflow の基礎13.ワークフロー特有の記述14.ワークフロージョブとデータの永続化
240
ワークフロー編12. Windows PowerShell Workflow とは
241
想定している利用シーン
ターゲットとなる処理
• 長時間を要する処理– 仮想マシンの展開
– ソフトウェアのインストール
– ビッグデータの集計 など
• 複数の処理の組み合わせ
• 複数のコンピューターに対する処理– ドメイン参加
– 環境設定
– インベントリ収集 など
要求される制御機構• タイムアウトやリトライ• 処理の一時停止、再開• 処理ステートの永続化• 複数処理の制御
• 並列• シーケンシャル
• スクリプト実行権限の委任• 途中経過の取得
ワークフロー = バックグラウンドジョブ + リモーティング + 実行制御
242
ユーザーリストをチェック
ホームディレクトリ作成
ユーザー作成
(例)ユーザーを作成する
UserList
ユーザー属性設定
グループメンバーシップ
パスワード設定
アクセス権設定
ユーザーごとの処理
完了
243
PowerShell 3.0 - ワークフロー
パラレル
WF
ジョブと結果の永続化
WF
処理1
処理2
checkpoint
結果ストア
結果1
checkpoint
処理3
サーバーダウン
サスペンド
WF
処理1
処理2
サスペンドサーバーが条件に合致しない場合にサスペンドし、あとでレジューム
244
PowerShell ワークフローの特長• 実行中のコンピューターが再起動してもワークフロージョブは消えない
• 一時停止状態(Suspend)になる• 長時間タスクの制御と監視
• アクティビティの進行状況はいつでも参照可能• 自動リカバリ
• 途中経過は指定したポイントで保存されている• ワークフローセッションへの接続と切断
• ワークフローを開始した PC とは別の PC から再接続が可能• 同時に複数コンピューターへの接続
• ワークフロータスクを同時に大量のサーバーに配信可能• 複数のスクリプトを1つのワークフローでコントロール• スケジューリング
• 特定の状態をトリガーとして起動可能• XAMLファイルでインポート、エクスポート可能
※ ワークフローが動作するコンピューターには Windows PowerShell 3.0 が必須
245
ワークフロー編13. Windows PowerShell Workflow の基礎
246
ワークフロ―実行までの流れ
① ワークフローを作成する
② ワークフローを登録する
③ ワークフローを確認する
④ ワークフローを実行する
i. ワークフローセッションの作成
ii. ワークフローを実行
iii. 結果を取得
247
Wokflow の作成
• PowerShell ISE(またはテキストエディタ) で作成する• workflow キーワードを使用する
workflow <ワークフロー名> ( <引数> )
{<処理>
}
workflow MyWorkflow ( [String] $ServiceName )
{
Get-Service -PSComputerName $PSComputerName -Name $ServiceName
}
(例)MyWorkflow という名前でリモートコンピューターのサービス一覧を取得するワークフロー
注意 -ComputerName ではない(後述)
共通パラメタ(後述)
248
Workflow の登録
• .ps1 で保存し、実行するだけまたは、PowerShell ISE 上から実行するだけ
• 留意点 どこに登録するか? いつ登録するか?
249
Workflow をどこに登録するか?
自分のPC Managed
Node
WF
自分のPCManaged
NodeWF 実行
WF
Win
RM
Win
RM
WM
IW
MI
In-Process Execution終わるまで家に帰れない!
Execution in Workflow Configuration実行したらセッッション切断して帰宅 :)
ワークフローは実行するノードに存在しなければならない
250
Workflow の登録先と実行環境について
• In-process 実行
Activity はローカルに登録される PowerShell クライアントホスト上での実行 ワークフローが終了するまでセッションを切断できない
• Workflow セッション上での実行
Activity はリモートノードに登録される Workflow 用に PS セッションを作成し、WinRM を通して実行する 一時的な切断が可能で、長時間のジョブを実行する際に便利
251
(参考)In-Process 実行時のアーキテクチャ
Localhost
Powershell.exe
Activity Host Process
Activity
Host
Managed Node
PowerShell
Remoting
(RSRP)
Managed Node
CIMOM/
WMI
PSWF
ExecutivePSWF
Cmdlets
252
(参考)Workflow セッションで実行時のアーキテクチャ
Managed Node
PowerShell
Remoting
(RSRP)
Managed Node
CIMOM/
WMI
PowerShell Workflow
Activity Host Process
Activity
Host
PSWF
Executive
Client
PSJobProxy/
PSJob API/
PSRP
WinRM
ClientWinRM
Service
253
Proxy Node
• リモートノードにワークフローを登録=リモートでスクリプトを実行
自分のPC 登録
WF
Managed
Node
Win
RM
WM
IManaged
NodeW
inR
MW
MI
Managed
Node
Win
RM
WM
I
実行
Win
RM
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 }
PS1ファイルがリモートにある場合
254
ワークフローをいつ登録すべきか?注意 ワークフローは セッション または PSセッション 内でのみ有効
PS C:¥> Invoke-Command -ComputerName NODE -FilePath .¥mywf.ps1
ダメな例2:登録したとたんに消滅
PS C:¥> $S = New-PSSession -ComputerName NODE
PS C:¥> Invoke-Command -Session $S -FilePath .¥mywf.ps1
ダメじゃないけど気をつけなければならない例:PS セッション消滅とともにWFも消滅
PS C:¥>.¥mywf.ps1
ダメな例1:コンソールを閉じた瞬間に消滅 orz
ワークフローは実行直前に登録したほうがよさそう...
PS C:¥> Invoke-Command -ComputerName NODE -FilePath .¥mywf.ps1 -asjob
255
(参考)workflow を登録すると...
AST(abstract syntax tree)workflow
{
Get-Service
}
.ps1 ファイル
実行
“workflow” キーワード検出
Script-to-workflow コンパイラ
XAML
workflow
Activity Tree
Workflow Foundation 4
ActivityXamlService Class
256
登録されたワークフローの確認
• Get-Command で確認する(ワークフローはコマンドレットと同じように扱える)
PS C:¥> Get-Command <ワークフロー名>
PS C:¥> Get-Command MyWorkflow
CommandType Name ModuleName----------- ---- ----------Workflow MyWorkflow
257
(参考)ワークフローに登録されるラッパー関数の確認
PS C:¥> Get-Command MyWorkflow |Get-Member
TypeName: System.Management.Automation.WorkflowInfo
Name MemberType Definition ---- ---------- ----------Equals Method bool Equals(System.Object obj) GetHashCode Method int GetHashCode() GetType Method type GetType() ResolveParameter Method System.Management.Automation.ParameterMetada...ToString Method string ToString() CmdletBinding Property bool CmdletBinding {get;} ・・・RemotingCapability Property System.Management.Automation.RemotingCapabil...ScriptBlock Property scriptblock ScriptBlock {get;} Verb Property string Verb {get;} Visibility Property System.Management.Automation.SessionStateEnt...WorkflowsCalled Property System.Collections.ObjectModel.ReadOnlyColle...XamlDefinition Property string XamlDefinition {get;} HelpUri ScriptProperty System.Object HelpUri {get=$oldProgressPrefe...
258
(参考)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[]">
<ns1:PowerShellValue x:TypeArguments="ns0:String[]" Expression="$PSComputerName" />
259
ワークフローの実行
コマンドレットと同じように実行すればよい
留意点• どこで実行するか?
ローカルで実行するとローカルコンピューターは落とせない• どこに結果を蓄積するか?
結果を蓄積するコンピューターは落とせない 複数のコンピューターに結果が散在すると結果を得るのが面倒
• 「共通パラメタ」を使用する必要がある
PS C:¥> MyWorkflow
260
復習~バックグラウンドジョブ
-AsJob の場合
SRC Target実行
結果
結果はローカルに戻される
Start-Job を使用する場合
SRC1 Target実行
結果
結果はリモートに保存される。セッションを永続化すれば別のコンピューターから取り出せる。
SRC2
Invoke-Command ーSession $S { ..... } -AsJob
Invoke-Command { Start-Job ・・・・}
261
リモートサーバー
PSWorkflowSession
Managed
Node
Managed
Node
Managed
Node
Managed
Node
(推奨)リモートで実行し、1箇所に結果を集める
実行
実行
実行
実行
結果を参照
実行
結果
PSWorkflowSession実行支持
ローカル
PC2
ローカル
PC1
事前にワークフローを登録しておく
Invoke-Command ーSession $S { WorkflowName -AsJob }
262
ワークフローの実行例
1. Workflow セッションを作成
2. Workflow をリモートで実行(リモートに Workflow が登録されている必要がある)
3. Workflow セッションを切断(セッションは生かしておく)
C:¥> $S = New-PSWorkflowSession -ComputerName PROXYNODE
C:¥>Invoke-Command $S { MyWorkflow -ServiceName WinRM
-PSComputerName TARGET1,TARGET2,TARGET3 -AsJob }
workflow MyWorkflow ( [String] $ServiceName )
{
Get-Service -PSComputerName $PSComputerName -Name $ServiceName
}
登録されているワークフロー
共通パラメタ
ジョブとして実行結果は、-PSComputerName で指定したコンピューター個々に保存される
C:¥> Disconnect-PSSession $S
263
New-PSWorkflowSession
• 規定では New-PSSession で作られる PS セッションと同じ設定• ワークフロー用に構成情報を独自に設定することができる
PS C:¥> (New-PSworkflowSession).ConfigurationName
Microsoft.PowerShell.Workflow
PS C:¥> Get-PSSessionConfiguration Microsoft.PowerShell.WorkflowName : microsoft.powershell.workflowPSVersion : 3.0StartupScript : RunAsUser : Permission : BUILTIN¥Administrators AccessAllowed, BUILTIN¥Remote Management Users AccessAllowed
PS C:¥> (New-PSSession).ConfigurationName
Microsoft.PowerShell
PS C:¥> Get-PSSessionConfiguration Microsoft.PowerShellName : microsoft.powershellPSVersion : 3.0StartupScript : RunAsUser : Permission : BUILTIN¥Administrators AccessAllowed, BUILTIN¥Remote Management Users AccessAllowed
264
PSWorkflow モジュール
• Windows PowerShell WorkFlow セッション を管理するためのモジュール
• 2つのコマンドレット
New-PSWorkflowSession
• ワークフロー用 PS セッションを作成する
New-PSWorkflowExecutionOption
• ワークフローセッションの構成情報を含んだオブジェクトを作成する
265
共通パラメタとは
Get-WmiObject -Class Win32_ComputerSystem -PSComputerName TARGET01
-PSCredential $PSCredentials
Get-WmiObject -Class Win32_ComputerSystem -ComputerName TARGET01
-Credential $PSCredentials
• ワークフロー内部、引数で使用できる特殊なパラメタ• ワークフローの処理を効率化するために用意されている• “PS” で始まる• コマンドレットのパラメタ名も同様に変わることに注意
通常のスクリプト
Workflow
266
C:¥>MyWorkflow -PSComputerName SV01,SV02,SV03,SV04
-PSCredential tf¥administrator
workflow MyWorkflow
{
Get-WmiObject -Class Win32_ComputerSystem
-PSComputerName $PSComputerName -PSCredential $PSCredential
}
共通パラメタは引数を定義する必要は無い
共通パラメタは、引数を定義する必要が無い
パラメタ名も共通パラメタにあわせる
パラメタ名も共通パラメタにあわせる
267
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)。
268
パラメタ名 意味
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 ワークフローの引数
269
ワークフロージョブの確認と結果の取得
バックグラウンドジョブと同様の手法で取得する
PS C:¥> Invoke-Command -Session $S { Get-Job }
Id Name PSJobTypeName State HasMoreData Location -- ---- ------------- ----- ----------- --------1 Job1 PSWorkflowJob Completed True tfdc02,tfsv01,tfsv02
PS C:¥> Invoke-Command -Session $S { Receive-Job -Id 1 -Keep }
Status Name DisplayName PSComputerName------ ---- ----------- --------------Running WinRM Windows Remote Management (WS-Manag... tfdc01 Running WinRM Windows Remote Management (WS-Manag... tfdc01 Running WinRM Windows Remote Management (WS-Manag... tfdc01
注意
270
ここで...JOB オブジェクトについて
PS C:¥> $JOB = Invoke-Command -Session $S { Get-Job }
PS C:¥> $JOB
Id Name PSJobTypeName State HasMoreData Location -- ---- ------------- ----- ----------- --------1 Job1 PSWorkflowJob Completed True tfdc02,tfsv01,tf...
PS C:¥> $JOB.ChildJobs
Id Name PSJobTypeName State HasMoreData Location -- ---- ------------- ----- ----------- --------2 Job2 PSWorkflowJob Completed True tfdc02 3 Job3 PSWorkflowJob Completed True tfsv01 4 Job4 PSWorkflowJob Completed True tfsv03
Deserialized.System.Management.Automation.ContainerParentJob
Deserialized.Microsoft.PowerShell.Workflow.PSWorkflowJob
各ノード(Location)ごとの処理は、ChildJob として管理されている
JOBを実行した場所
271
PS C:¥> $JOB |Get-Member
TypeName: Deserialized.System.Management.Automation.ContainerParentJob
Name MemberType Definition ---- ---------- ----------ToString Method string ToString(), string ToString(string format, System.IFor...PSComputerName NoteProperty System.String PSComputerName=tfdc01 PSShowComputerName NoteProperty System.Boolean PSShowComputerName=True RunspaceId NoteProperty System.Guid RunspaceId=ebcb1d6d-60b6-460b-b2b4-23a065bab884 State NoteProperty System.String State=Completed ChildJobs Property Deserialized.System.Collections.Generic.List`1[[System.Manage...Command Property System.String {get;set;} HasMoreData Property System.Boolean {get;set;} Id Property System.Int32 {get;set;} InstanceId Property System.Guid {get;set;} JobStateInfo Property System.Management.Automation.JobStateInfo {get;set;} Location Property System.String {get;set;} Name Property System.String {get;set;} PSBeginTime Property System.DateTime {get;set;} PSEndTime Property System.DateTime {get;set;} PSJobTypeName Property System.String {get;set;} StatusMessage Property System.String {get;set;}
272
ワークフロー結果の取得(再び)
PS C:¥> Invoke-Command -Session $S {Get-Job -IncludeChildJob}
Id Name PSJobTypeName State HasMoreData Location Command -- ---- ------------- ----- ----------- -------- ------1 Job1 PSWorkflowJob Completed False tfdc02,tfsv01,tfsv03 myw...2 Job2 PSWorkflowJob Completed False tfdc02 MyW...3 Job3 PSWorkflowJob Completed False tfsv01 MyW...4 Job4 PSWorkflowJob Completed False tfsv03 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 }
273
ワークフロー編14. Windows PowerShell Workflow 特有の記述
274
基本動作
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:¥>
ワークフロー 実行結果
275
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,tfsv02tfsv01 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
複数のコンピューターを指定した場合には、処理自体はシーケンシャルだがコンピューター単位で非同期に実行される
276
並列処理
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
}
ワークフロー
この部分は
並列処理
277
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:582012年6月18日 18:50:59
実行結果
278
並列処理の中のシーケンシャル処理
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
}
この部分は
シーケンシャル
並列
279
並列処理の例
Workflow JoinDomain ([string] $Domain)
{Add-Computer -PSComputerName $PSComputerName ‘
-DomainName $Domain –Credential $PSCredential
Restart-Computer -PSComputerName $PSComputerName -Wait `
-For PowerShell -Force
}
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
ワークフローを実行
リモートコンピューターを一斉にドメインに参加させる
ComputerName
Client01
Client02
Client03
Client04
Client05
280
foreach -parallel
配列内の各要素に関して同時に実行する
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
}
}
ComputerName
Client01
Client02
Client03
Client04
Client05
PS C:¥> JoinDomain -Domain CONTOSO -ClientList .¥ClientList.txt -PSCredential $Cred
(注意)1行ごとに並列処理される
281
お勧めできない並列処理
単一ノードに対して一斉処理を行う
(例)1000人のユーザーを並列で作成する
workflow CreateNewUser([string[]] $IDs)
{
foreach -parallel($ID in $IDs)
{
New-ADUser -Name user$ID -PasswordNeverExpires $true
}
}
ダメな並列処理の例
282
ワークフロー編15. ワークフロージョブとデータの永続化
283
ジョブの永続化何もしなくてもワークフロージョブ(PSWorkflowJob)は永続化される※ Remove-Job しない限り消えない
PS C:¥tools¥ps¥wf> Invoke-Command -Session $S { Get-Job }
Id Name PSJobTypeName State HasMoreData Location -- ---- ------------- ----- ----------- --------1 Job1 PSWorkflowJob Running True localhost14 Job7 PSWorkflowJob Completed True tfsv01,tfdc02,tf...15 Job3 PSWorkflowJob Suspended True localhost16 Job1 PSWorkflowJob Completed True tfsv03,tfsv01,tf...17 Job15 PSWorkflowJob Stopped True localhost18 Job1 PSWorkflowJob Suspended True localhost19 Job1 PSWorkflowJob Completed True localhost20 Job41 PSWorkflowJob Suspended True localhost一時停止
完了
実行中
停止
Invoke-Command -Session $S { Get-Job | Stop-Job}
Invoke-Command -Session $S { Get-Job | Remove-Job }
すべてのジョブを停止して削除する(Stopped にならないと削除できない)
284
データの永続化(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 を指定すると自動的にすべての出力が永続化される
285
ワークフロージョブのレジューム
PS C:¥tools¥ps¥wf> Invoke-Command -Session $s {Resume-Job 2}
Id Name PSJobTypeName State HasMoreData Location -- ---- ------------- ----- ----------- --------2 Job3 PSWorkflowJob Suspended True localhost
PS C:¥tools¥ps¥wf> Invoke-Command -Session $s {Get-Job 2}
Id Name PSJobTypeName State HasMoreData Location-- ---- ------------- ----- ----------- --------2 Job3 PSWorkflowJob Running True localhost
286
ワークフローのサスペンド• ワークフローを強制的に一時停止できる• 実行条件に合わないときなどに使用する※サーバーの再起動時にも自動的にサスペンドされる
Suspended 状態に移行する際に、データは自動的に永続化される
PS C:¥tools¥ps¥wf> Invoke-Command -Session $s {get-job 2}
Id Name PSJobTypeName State HasMoreData Location -- ---- ------------- ----- ----------- --------2 Job3 PSWorkflowJob Running True localhost
PS C:¥tools¥ps¥wf> Invoke-Command -Session $s {Suspend-job 2}
Id Name PSJobTypeName State HasMoreData Location -- ---- ------------- ----- ----------- --------2 Job3 PSWorkflowJob Suspending True localhost
PS C:¥tools¥ps¥wf> Invoke-Command -Session $s {get-job 2}
Id Name PSJobTypeName State HasMoreData Location -- ---- ------------- ----- ----------- --------2 Job3 PSWorkflowJob Suspended True localhost
287
(例)大量のユーザーを登録するワークフロー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.userIDEcho -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
}
}
288
Domain
Controller
(DC01)
Stopped
Running
Suspended
Running
$S = New-PSWorkflowSession -ComputerName DC01
Invoke-Command -Session $S -FilePath .¥CreateNewUser.ps1
PSワークフローセッションを張る
ワークフローをDC01上に作成する
Invoke-Command -Session $S {Get-Command -CommandType Workflow}
ワークフローが作られたことを確認
Invoke-Command -Session $S {CreateUser -PSPersist $true -ErrorAction SilentlyContinue -AsJob}
ワークフローを実行
DC01 が停電によりシャットダウン
DC01 が復電により再起動
$S = New-PSWorkflowSession -ComputerName DC01
もう一度セッションを張る
Invoke-Command -Session $S { Get-Job }ジョブIDを確認
Invoke-Command -Session $S { Resume-Job 3 }ジョブをレジューム
ローカルP
C
実行までの流れ
289
ワークフロージョブのスケジュール
Add-JobTrigger
Disable-JobTrigger
Disable-ScheduledJob
Enable-JobTrigger
Enable-ScheduledJob
Get-JobTrigger
Get-ScheduledJob
Get-ScheduledJobOption
• 条件をトリガーにしてワークフロージョブを起動(Start, Resume)することができる
New-JobTrigger
New-ScheduledJobOption
Register-ScheduledJob
Remove-JobTrigger
Set-JobTrigger
Set-ScheduledJob
Set-ScheduledJobOption
Unregister-ScheduledJob
290
Part 5 開発者編
291
Agenda
16. 開発者にとっての Windows PowerShell とは17. 開発者のための Windows PowerShell 基礎知識18. 開発者として必要な情報の取得19. コマンドレット以外からオブジェクトのインスタンスを作成する20. Visual Studio(C#)から PowerShell を呼び出す
292
開発者編16. 開発者にとっての Windows PowerShell とは
293
Question
ある開発案件で、Active Directory Domain Service(AD DS) のユーザー管理アプリを開発することになりました。AD DS は正直よく知りませんし、Directory Service 用の API を一から調べるのも面倒です。
294
マイクロソフト製品と PowerShell の関係
• 製品ごとに専用の”コマンドレット”が用意されている• 多くの管理 GUI は裏でコマンドレットを呼んでいる• 各製品への”標準化されたアクセス方法”を提供する
Active Directory
Active DirectoryPowerShell コマンドレット
Active Directory管理センター
Exchange Server 2010
Exchange Server 用PowerShell コマンドレット
Exchange 2010管理コンソール
PowerShellコンソール
重要!
295
PowerShell は開発工数を低減するために存在する
• 目的ベースのコマンドレット(CmdLet)• アプリケーションに対する処理の正確性• ビジネスにとっての高速性
• オペレーション品質と開発品質の向上• 自動化• ビジネスに合わせた拡張性
Active Directory
ユーザーリストを取得
ユーザーを削除
ユーザーを探す
API
Get-ADUser
目的 コマンドレット
Remove-ADUser
Search-ADAccount
296
(例)Active Directory に30日間ログオンしていないユーザー一覧を取得する
Search-ADAccount –AccountInactive –TimeSpan 30 -UsersOnly
| ft name
たったこれだけ!
297
使えるのは
約 3000 Cmdlets
.NET FrameworkWindows Server 2012 R2 リリース時点
298
Windows
.NET Framework
PowerShell スクリプト
CLR(共通言語ランタイム)
Class Library
Windows PowerShell の実行環境
PowerShell エンジン
COM
PowerShell コマンドレット
299
.NET Framework と PowerShell の関係
PowerShell コマンドレットから .NET Framework を呼び出す
.NET Framework からPowerShell コマンドレットを呼び出す
300
開発者編17. 開発者のための Windows PowerShell 基礎知識
301
開発者編18. 開発者として必要な情報の取得
302
C:¥> $a = [System.Math]::Pow(2,3)
C:¥> $a.GetType()
IsPublic IsSerial Name BaseType-------- -------- ---- --------True True Double System.ValueType
オブジェクトのタイプを参照する
C:¥> ( 1 ).GetType()
IsPublic IsSerial Name BaseType-------- -------- ---- --------True True Int32 System.ValueType
PS C:¥Windows¥system32> (Get-Service).GetType()
IsPublic IsSerial Name BaseType-------- -------- ---- --------True True Object[] System.Array
303
C:¥> Get-Service | Get-Member
TypeName: System.ServiceProcess.ServiceController
Name MemberType Definition ---- ---------- ----------Name AliasProperty Name = ServiceNameRequiredServices AliasProperty RequiredServices = ServicesDependedOnDisposed Event System.EventHandler Disposed(System.Object, System.EventArgs) Close Method System.Void Close() Continue Method System.Void Continue() CreateObjRef Method System.Runtime.Remoting.ObjRef CreateObjRef(type requestedT...Dispose Method System.Void Dispose() Equals Method bool Equals(System.Object obj) ExecuteCommand Method System.Void ExecuteCommand(int command) GetHashCode Method int GetHashCode() GetLifetimeService Method System.Object GetLifetimeService() GetType Method type GetType() InitializeLifetimeService Method System.Object InitializeLifetimeService() Pause Method System.Void Pause() Refresh Method System.Void Refresh() Start Method System.Void Start(), System.Void Start(string[] args) Stop Method System.Void Stop() WaitForStatus Method System.Void WaitForStatus(System.ServiceProcess.ServiceCont...CanPauseAndContinue Property bool CanPauseAndContinue {get;} CanShutdown Property bool CanShutdown {get;} CanStop Property bool CanStop {get;} Container Property System.ComponentModel.IContainer Container {get;} DependentServices Property System.ServiceProcess.ServiceController[] DependentServices...DisplayName Property string DisplayName {get;set;}
メンバー(メソッド、プロパティ)を参照する
クラス名
304
PS > Get-Service | Get-Member -MemberType Method
TypeName: System.ServiceProcess.ServiceController
Name MemberType Definition ---- ---------- ----------Close Method System.Void Close() Continue Method System.Void Continue() CreateObjRef Method System.Runtime.Remoting.ObjRef CreateObjRef(type requestedType) Dispose Method System.Void Dispose() Equals Method bool Equals(System.Object obj) ExecuteCommand Method System.Void ExecuteCommand(int command) GetHashCode Method int GetHashCode() GetLifetimeService Method System.Object GetLifetimeService() GetType Method type GetType() InitializeLifetimeService Method System.Object InitializeLifetimeService() Pause Method System.Void Pause() Refresh Method System.Void Refresh() Start Method System.Void Start(), System.Void Start(string[] args) Stop Method System.Void Stop() WaitForStatus Method System.Void WaitForStatus(System.ServiceProcess.ServiceControl...
メソッドだけ表示
305
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.dllPowerShell_ISE.exeMicrosoft.PowerShell.ISECommon.dllSystem.dllSystem.Windows.Forms.dllSystem.Drawing.dllSystem.Management.Automation.dllSystem.Core.dllMicrosoft.PowerShell.GPowerShell.dllSystem.ComponentModel.Composition.dllMicrosoft.PowerShell.Editor.dllPresentationFramework.dllWindowsBase.dllPresentationCore.dllSystem.Xaml.dllSystem.Configuration.dllSystem.Xml.dllSystem.Runtime.Serialization.dllUIAutomationProvider.dllAccessibility.dllSystem.Numerics.dll
System.Management.dllSystem.DirectoryServices.dllMicrosoft.Management.Infrastructure.dllPresentationCore.resources.dllPresentationFramework.Aero.dllUIAutomationTypes.dllSystem.Configuration.Install.dllSystem.Transactions.dllMicrosoft.PowerShell.Security.dllSystem.Data.dllMicrosoft.PowerShell.GraphicalHost.dllmscorlib.resources.dllMicrosoft.CSharp.dllPresentationFramework.resources.dllMicrosoft.PowerShell.Commands.Management.dllMicrosoft.PowerShell.Commands.Utility.dllMicrosoft.iX.ScriptExplorer.PSISE.dllMicrosoft.iX.ScriptExplorer.AgentIntegrationService.Interfaces.dllSystem.ServiceModel.Web.dllSystem.ServiceModel.dll
SMDiagnostics.dllMicrosoft.iX.ScriptExplorer.AgentIntegrationService.dllSystem.Runtime.DurableInstancing.dllSystem.WorkflowServices.dllSystem.ServiceModel.Discovery.dllSystem.ServiceModel.Activities.dllSystem.ServiceModel.Routing.dllMicrosoft.VisualStudio.Diagnostics.ServiceModelSink.dllSystem.ServiceModel.Channels.dllSystem.ServiceModel.Web.resources.dllSystem.IdentityModel.dllSystem.resources.dllSystem.ServiceProcess.dll
306
開発者編19.コマンドレット以外からオブジェクトのインスタンスを作成する
307
コマンドレット以外からオブジェクトのインスタンスを作成する方法
• New-Object -ComObject <ProgID>
• New-Object -TypeName <Class Name>
• [<Class Name>]::<Member()>
308
COM オブジェクトを作成する
PS > $excel = New-Object -ComObject Excel.Application
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 >$worksheet = New-Object -ComObject Excel.Sheet.12
PS >$worksheet.SaveAs( “C:¥Tmp¥test.xlsx”)
309
ProgID を調べるには
OLE Viewer
310
$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)
$ie.ExecWB(4,0,$null,[ref ]$null)
例:指定したURLのページを保存するスクリプト
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
311
$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"
例:パフォーマンスデータを Excel シートに 書き込むスクリプト
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
$Cells.Item($row,6) = "Average“
Do
{
$perf =Get-WmiObject `
-Class win32_perfformatteddata_perfos_processor `
-Property PercentProcessorTime
$i = 1
$row++
$cells.Item($row,1) = `
(Get-Date -format "yyyy/MM/dd hh:mm:ss").tostring()
foreach ($p in $perf) {
$i++
$Cells.Item($row,$i) = $p.PercentProcessorTime
If ($p.PercentProcessorTime -ge 20) `
{$Cells.Item($row,$i).Interior.ColorIndex = 3}
}
Start-Sleep -Seconds 1
} while (-1)
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
312
PowerShell から .NET Framework を呼ぶには
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”)
New-Object <ClassName>
• インスタンスが作成可能なクラスの場合
PS C:¥> [System.math]::Pow(15,3)
3375
[<ClassName>]::<Member(Param)>
• インスタンスを持たない静的クラスの場合
※IntelliSense サポート
313
静的クラス• 静的メンバーのみを含んでいる• メソッドやプロパティのリファレンス• 新しいオブジェクトを作成することができない
PS C:¥> [System.math] | Get-Member
TypeName: System.RuntimeType
PS C:¥> [System.Math] | Get-Member -static
TypeName: System.Math
Name MemberType Definition---- ---------- ----------Abs Method static System.SByte Abs(System.SByte value), static System.Int16 Acos Method static double Acos(double d) Asin Method static double Asin(double d)Atan Method static double Atan(double d)Atan2 Method static double Atan2(double y, double x)・・・
静的クラスは RuntimeType になる
正しいメンバーを参照するには -Static を付ける
314
静的クラスの例PS > [System.Environment]::CommandLine"C:¥Windows¥system32¥WindowsPowerShell¥v1.0¥PowerShell_ISE.exe"
PS > [System.Environment]::OSVersion
Platform ServicePack Version VersionString-------- ----------- ------- -------------Win32NT Service Pack 1 6.1.7601.65536 Microsoft Windows NT ...
PS >[System.Environment]::HasShutdownStartedFalse
PS > [system.appdomain]::CurrentDomain
FriendlyName : PowerShell_ISE.exeId : 1ApplicationDescription : BaseDirectory : C:¥Windows¥system32¥WindowsPowerShell¥v1.0¥DynamicDirectory : RelativeSearchPath : SetupInformation : System.AppDomainSetupShadowCopyFiles : False
315
New-Object の利用例
ウィンドウを作成する(リストボックス)Remove-Variable x
Add-Type -AssemblyName "System.Windows.Forms"
Add-Type -AssemblyName "System.Drawing"
$objForm = New-Object System.Windows.Forms.Form$objForm.Text = "リストボックス"
$objForm.Size = New-Object System.Drawing.Size(300,200)
$objForm.StartPosition = "CenterScreen"
$OKBtn = New-Object System.windows.Forms.Button
$OKBtn.Location = New-Object System.Drawing.Size(100,120)
$OKBtn.Size = New-Object System.Drawing.Size(75,20)
$OKBtn.Text = "OK"
$objListbox = New-Object System.Windows.Forms.Listbox
$objListbox.Location = New-Object System.Drawing.Size(15,20)
$objListbox.Size = New-Object System.Drawing.Size(260,80)
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
316
.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")
以下の書き方は旧式
アセンブリ名で指定する
Add-Type -Path c:¥tmp¥hoge.dll
DLL ファイル名で指定する
317
どんなときにロードが必要か?
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
NetPopup : False
BeepEnabled : False
使用したいクラスを含むアセンブリがロードされていない場合
エラー
318
自分で定義したクラスをロードする
$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 と呼ばれる記法
@”
“@
ここに記述した文字列がそのまま維持される
319
開発者編20. Visual Studio(C#)から PowerShell を呼び出す
320
完成されたコマンドレットに処理を代行させる
using System;
public class hogehoge {
public String hogehogehoge {
}
}
Get-Service
Get-Process
Move-VM・・・・
PowerShell 呼び出し
結果を受け取り
PowerShell RunSpaceC# ソースコード
PowerShell RunSpace を作成してコマンドレットを実行
321
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() で実行
322
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() );
}
PowerShell からプロセス一覧を取得
Get-Process
323
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() );
}
PowerShell からプロセス一覧を取得
Get-Process -Name notepad
位置パラメタを指定する場合に使用する
324
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() );
}
Get-Process -Name MS* | Sort-Object -Property ID -descending
名前付きパラメタを指定する場合に使用する
パイプで接続されたコマンドレット
325
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() );
}
Get-Process -Name MS* | Sort-Object -Property ID -descending
コマンドレットをそのまま書けばよい
326
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() );
}
RunSpace を明に指定した例
327
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() );
}
コマンドの代わりに PS1 ファイルを指定する
¥ではなく¥¥
328
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() );
}
RunSpace から PipeLine を明に作成して、AddScript にスクリプトを指定する方法
※これはコンソールアプリです
329
Get-Process | Format-Table ID, Name, WorkingSet, Handles -AutoSize | Out-
String -Width 90
PowerShell 側の出力結果に注意
PowerShell 側で加工しすぎると、Visual Studio で扱いづらくなる
見た目は良くなるが 1つのストリームで返されるため、ループ等によって項目ごとの処理が行いづらい
330
(参考)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();
Visual Studio 上で作成したデータを PowerShell に渡すことも可能
331
さらに詳しく
PowerShell Classhttp://msdn.microsoft.com/en-us/
library/system.management.automation.powers
hell(v=vs.85).aspx
332