Operations Lab.

Archive for 1月 2015

PowerShell の $a –eq $b と $b –eq $a は同じ結果とは限らない

leave a comment »

一言で言うと、タイトルの通りなのですが。他の言語を使用している方は、(普段使っている言語によっては)違和感があるかもしれません。

もともと、PowerShell の –eq 演算子は、配列(リスト)に適用したときと値型(Scalar Value)に適用したときで動作が異なります。が、値型同士の比較であっても、結果が異なる場合があります。

PS C:\> $true -eq 10
True
PS C:\> 10 -eq $true
False

$true は bool 型、10 は int 型で、ともに値型ですが、上記の通り異なる結果になります。これは、Boolean や Null ($null)と数値を比較した場合、右側のオペランド(被演算子)が左オペランドの型へ暗黙的にキャストされるためです。ですので、上の例は、以下と同等になります。

PS C:\> [bool]10
True
PS C:\> $true -eq [bool]10
True
PS C:\> [int]$true
1
PS C:\> 10 -eq [int]$true
False

ちなみに、通常の数値型(int や double 等)を –eq 演算子で比較した場合は、左オペランドの型へキャストされるのではなく、左右のオペランドのうち精度の高い型や範囲の広い型へキャストされます。(つまり、必ず左オペランドの型へキャストされるわけではありません。)

PS C:\> 10 -eq 10.1
False
PS C:\> 10.1 -eq 10
False
参考

Written by kazu

2015/01/31 at 11:30

PowerShell で「続行しますか?」に「中断」を選択するとどうなるか

leave a comment »

文字通り「中断」されるのですが、「中断」って何?というお話。

例えば、Enable-PSRemoting コマンドレットをオプションなしで実行すると、以下の通り確認のプロンプトが表示されます。

PS C:\> Enable-PSRemoting

WinRM クイック構成
Windows リモート管理 (WinRM) サービスを使用して、このコンピューターのリモート管理を有効にするコマンド
"Set-WSManQuickConfig" を実行します。
 これには、次の処理が含まれます:
    1. WinRM サービスを開始または (既に開始されている場合は) 再起動します。
    2. WinRM サービスのスタートアップの種類を [自動] に設定します。
    3. どの IP アドレスでも要求を受け付けるリスナーを作成します。
    4. WS-Management トラフィック用の Windows ファイアウォールの受信規則の例外を有効にします (HTTP のみ)。

続行しますか?
[Y] はい(Y)  [A] すべて続行(A)  [N] いいえ(N)  [L] すべて無視(L)  [S] 中断(S)  [?] ヘルプ (既定値は "Y"):

続行する場合は「はい」、続行しない場合(キャンセルする場合)は「いいえ」を選択すればよいのですが、それ以外に「中断」が選択できます。(なお、基本的には「すべて続行」は「すべてはい」、「すべて無視」は「すべていいえ」と同等です。)

「中断」を選択した場合は以下の様になります。

続行しますか?
[Y] はい(Y)  [A] すべて続行(A)  [N] いいえ(N)  [L] すべて無視(L)  [S] 中断(S)  [?] ヘルプ (既定値は "Y"): S
PS C:\>>

一見、「いいえ」と何が違うのかわかりませんが、よく見るとプロンプトの「>」の数が異なります。

実は(と言うほどでもないですが)、「中断」はコマンドの実行を保留したまま、シェルのプロンプトを表示します。(ネストされたシェルを呼び出します。)コマンドの実行は保留されているため、exit でプロンプトから抜けると、先程中断した(選択を保留した)個所から再開されます。

PS C:\>> Get-Service WinRM

Status   Name               DisplayName
------   ----               -----------
Running  WinRM              Windows Remote Management (WS-Manag...


PS C:\>> Get-Item WSMan:\localhost\Client\TrustedHosts


   WSManConfig: Microsoft.WSMan.Management\WSMan::localhost\Client

Type            Name                           SourceOfValue   Value
----            ----                           -------------   -----
System.String   TrustedHosts                                   *


PS C:\>> exit

WinRM クイック構成
Windows リモート管理 (WinRM) サービスを使用して、このコンピューターのリモート管理を有効にするコマンド
"Set-WSManQuickConfig" を実行します。
 これには、次の処理が含まれます:
    1. WinRM サービスを開始または (既に開始されている場合は) 再起動します。
    2. WinRM サービスのスタートアップの種類を [自動] に設定します。
    3. どの IP アドレスでも要求を受け付けるリスナーを作成します。
    4. WS-Management トラフィック用の Windows ファイアウォールの受信規則の例外を有効にします (HTTP のみ)。

続行しますか?
[Y] はい(Y)  [A] すべて続行(A)  [N] いいえ(N)  [L] すべて無視(L)  [S] 中断(S)  [?] ヘルプ (既定値は "Y"):

「中断」は、上記の様に、コマンドの実行途中で、選択を一時的に保留し、別のコマンドレットを実行(して状態の確認などを行う)際に使用します。

なお、何度も(ネストされている中でさらに)中断すると、プロンプトの「>」の数が増えていきます。(昔は増えない仕様だった気がするのですが…。)いずれにせよ、何度も中断すると、戻ってきたときにいったい何の処理中だったのか訳が分からなくなるので、複数中断しないほうが良いと思います。

PS C:\> Enable-PSRemoting

WinRM クイック構成
Windows リモート管理 (WinRM) サービスを使用して、このコンピューターのリモート管理を有効にするコマンド
"Set-WSManQuickConfig" を実行します。
 これには、次の処理が含まれます:
    1. WinRM サービスを開始または (既に開始されている場合は) 再起動します。
    2. WinRM サービスのスタートアップの種類を [自動] に設定します。
    3. どの IP アドレスでも要求を受け付けるリスナーを作成します。
    4. WS-Management トラフィック用の Windows ファイアウォールの受信規則の例外を有効にします (HTTP のみ)。

続行しますか?
[Y] はい(Y)  [A] すべて続行(A)  [N] いいえ(N)  [L] すべて無視(L)  [S] 中断(S)  [?] ヘルプ (既定値は "Y"): S
PS C:\>>
PS C:\>> Enable-PSRemoting

確認
この操作を実行しますか?
[Y] はい(Y)  [A] すべて続行(A)  [N] いいえ(N)  [L] すべて無視(L)  [S] 中断(S)  [?] ヘルプ (既定値は "Y"): S
PS C:\>>>
PS C:\>>> Enable-PSRemoting

確認
この操作を実行しますか?
[Y] はい(Y)  [A] すべて続行(A)  [N] いいえ(N)  [L] すべて無視(L)  [S] 中断(S)  [?] ヘルプ (既定値は "Y"): S
PS C:\>>>>
PS C:\>>>> exit

確認
この操作を実行しますか?
[Y] はい(Y)  [A] すべて続行(A)  [N] いいえ(N)  [L] すべて無視(L)  [S] 中断(S)  [?] ヘルプ (既定値は "Y"): L

確認
この操作を実行しますか?
対象 "" に対して操作 "" を実行しています。
[Y] はい(Y)  [A] すべて続行(A)  [N] いいえ(N)  [L] すべて無視(L)  [S] 中断(S)  [?] ヘルプ (既定値は "Y"): L
PS C:\>>> exit

確認
この操作を実行しますか?
[Y] はい(Y)  [A] すべて続行(A)  [N] いいえ(N)  [L] すべて無視(L)  [S] 中断(S)  [?] ヘルプ (既定値は "Y"): L

確認
この操作を実行しますか?
対象 "" に対して操作 "" を実行しています。
[Y] はい(Y)  [A] すべて続行(A)  [N] いいえ(N)  [L] すべて無視(L)  [S] 中断(S)  [?] ヘルプ (既定値は "Y"): L
PS C:\>> exit

WinRM クイック構成
Windows リモート管理 (WinRM) サービスを使用して、このコンピューターのリモート管理を有効にするコマンド
"Set-WSManQuickConfig" を実行します。
 これには、次の処理が含まれます:
    1. WinRM サービスを開始または (既に開始されている場合は) 再起動します。
    2. WinRM サービスのスタートアップの種類を [自動] に設定します。
    3. どの IP アドレスでも要求を受け付けるリスナーを作成します。
    4. WS-Management トラフィック用の Windows ファイアウォールの受信規則の例外を有効にします (HTTP のみ)。

続行しますか?
[Y] はい(Y)  [A] すべて続行(A)  [N] いいえ(N)  [L] すべて無視(L)  [S] 中断(S)  [?] ヘルプ (既定値は "Y"): L

確認
この操作を実行しますか?
対象 "名前: microsoft.powershell SDDL:
O:NSG:BAD:P(A;;GA;;;BA)(A;;GA;;;RM)S:P(AU;FA;GA;;;WD)(AU;SA;GXGW;;;WD)。選択したユーザーがこのコンピューターに対して
Windows PowerShell コマンドをリモートで実行できるようにします。" に対して操作 "Set-PSSessionConfiguration"
を実行しています。
[Y] はい(Y)  [A] すべて続行(A)  [N] いいえ(N)  [L] すべて無視(L)  [S] 中断(S)  [?] ヘルプ (既定値は "Y"): L
PS C:\>

「いいえ」で一旦処理をキャンセルし、確認後に改めてコマンドを実行してもよい状況であれば、「中断」は使わないほうが良いでしょう。その方が分かりやすく、オペレーションミスの可能性も低くなるはずです。

Written by kazu

2015/01/25 at 21:43