プログラミングのすすめ 第十一歩 Windows PowerShell リファレンス

プログラミング

プログラミングのすすめ 第十歩で始めた Windows PowerShell ですが、前回で分かったように Windows PowerShell はかなり高度です。プログラミングのすすめ 第六歩で、VBで作ったグラフ用データ作成プログラムも プログラミングのすすめ 第七歩のHTMLファイルの作成も PowerShell だけで代替することが出来ました。

今回は PowerShell でよく使われるコマンドレットや、メソッド、関数、演算子 等々を実際に実行しながら分かり易くまとめて行きたいと思います。

会員数は国内最大級の180万人を突破!【paters】
  1. よく使うコマンドレット
    1. Get-Content ファイルの内容を取得する
    2. Get-Date 現在の日付と時刻を取得する
    3. Select-String ファイル内のテキストを検索する
    4. Set-Location 現在の作業場所を指定された場所に設定します。
    5. Out-String 入力オブジェクトをストリングに変換する
    6. Out-File ファイルに書き出す
    7. Write-OutPut パイプラインに書き込む、コンソールに書き込む
    8. Add-Content ファイルに追加する
    9. Get-ChildItem ディレクトリの内容を取得する
    10. Rename-Item Itemの名前を変更する
    11. ForEach-Object 各入力オブジェクトに対して操作を実行する
    12. Format-List オブジェクトのプロパティをリスト形式で表示する
    13. Select-Object オブジェクト、オブジェクトのプロパティ を選択する
    14. Sort-Object オブジェクトのプロパティの値でオブジェクトを並べ変える
    15. Set-ExecutionPolicy スクリプトの実行ポリシーを変更する
      1. 実行ポリシー Unrestricted
        1. Unblock-File インターネットからダウンロードされたファイルのブロックを解除する
      2. 実行ポリシー RemoteSigned
      3. 実行ポリシー AllSigned
        1. デジタル署名の仕方
          1. 自己署名証明書の作成
          2. 署名用スクリプトの記述
          3. Add-Signature.ps1 に署名する
          4. 作成した自己証明書を移動する
          5. PowerShell から証明書を確認
          6. 信頼されたルート証明機関に移動した PowerShell Cord Signing Cert で署名する
      4. 実行ポリシー Restricted
      5. 実行ポリシー Default
      6. 実行ポリシー Bypass
      7. 実行ポリシー Undefined
    16. Test-Path ファイルの存在を調べる
  2. よく使う関数、演算子、メソッド
    1. PowerShell のプロンプトの変更
    2. Profile.PS1 の記述
    3. Substring メソッド 文字列から部分文字列の抽出
    4. $() 部分式演算子
    5. Split 演算子 文字列を分割する
    6. Count 演算子
    7. Replace 置換演算子
    8. .. 範囲演算子
    9. 配列変数の定義
    10. マルチ・ディメンジョンの配列
    11. ToCharArray() メソッド 文字列を一文字づつ配列に代入
  3. 応用編、およびスクリプト
    1. CSV ファイルのある条件の行を抽出する
    2. 与えられた期間指定の日付を判定するスクリプト
    3. PowerShell から他のアプリケーションを実行する
    4. 実行されているPowerShellが管理者で実行されているかを外部から調べる
    5. Visual Basic でPowerShell を使う

よく使うコマンドレット

Get-Content ファイルの内容を取得する

エイリアスは、 cat , gc ,type の三つが充てられています。

PS C:\PS_Work> Get-Alias -Definition Get-Content

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Alias           cat -> Get-Content
Alias           gc -> Get-Content
Alias           type -> Get-Content

Get-Content は、ファイルの内容を取得します。

-head で先頭から取得する項目数を指定できます。 -tail で末尾から取得する項目数を指定できます。

PS C:\PS_Work> cat test1.txt
This is test1 0 AAAA3,ABC,123,12345
This is line 2 of test1 1 bbbb3,2222,33333
This is line 3 test1 2 CCCC3
This is line 4 test1 3 dddd3,3333,4444,55555

PS C:\PS_Work> cat test1.txt -head 2
This is test1 0 AAAA3,ABC,123,12345
This is line 2 of test1 1 bbbb3,2222,33333

PS C:\PS_Work> cat test1.txt -tail 2
This is line 3 test1 2 CCCC3
This is line 4 test1 3 dddd3,3333,4444,55555

PowerShell でパラメータを入れる場合、他のパラメータと区別できるところまで短縮できます。この例では、Get-Content で使えるパラメータで h で始まるのは -head だけなので -h まで短縮できます。一方 -tail は、t で始まるパラメータは、他に -TotalCount が存在するので、 -ta までしか短縮できません。

PS C:\PS_Work> cat test1.txt -head 1
This is test1 0 AAAA3,ABC,123,12345

PS C:\PS_Work> cat test1.txt -hea 1
This is test1 0 AAAA3,ABC,123,12345

PS C:\PS_Work> cat test1.txt -he 1
This is test1 0 AAAA3,ABC,123,12345

PS C:\PS_Work> cat test1.txt -h 1
This is test1 0 AAAA3,ABC,123,12345

PS C:\PS_Work> cat test1.txt -tail 1
This is line 4 test1 3 dddd3,3333,4444,55555

PS C:\PS_Work> cat test1.txt -tai 1
This is line 4 test1 3 dddd3,3333,4444,55555

PS C:\PS_Work> cat test1.txt -ta 1
This is line 4 test1 3 dddd3,3333,4444,55555

PS C:\PS_Work> cat test1.txt -t 1
Get-Content : パラメーター名 't' があいまいなため、パラメーターを処理できません。一致する名前の候補は次のとおりです:  -TotalCount -Tail。
発生場所 行:1 文字:15
+ cat test1.txt -t 1

-head は、 -TotalCount , -First でも同じです。

PS C:\PS_Work> cat test1.txt -TotalCount 1
This is test1 0 AAAA3,ABC,123,12345

PS C:\PS_Work> cat test1.txt -Total 1
This is test1 0 AAAA3,ABC,123,12345

PS C:\PS_Work> cat test1.txt -Tot 1
This is test1 0 AAAA3,ABC,123,12345

PS C:\PS_Work> cat test1.txt -To 1
This is test1 0 AAAA3,ABC,123,12345

PS C:\PS_Work> cat test1.txt -First 1
This is test1 0 AAAA3,ABC,123,12345

PS C:\PS_Work> cat test1.txt -Fi 1
Get-Content : パラメーター名 'Fi' があいまいなため、パラメーターを処理できません。一致する名前の候補は次のとおりです:  -Filter -TotalCount。
発生場所 行:1 文字:15
+ cat test1.txt -Fi 1
+               ~~~
    + CategoryInfo          : InvalidArgument: (:) [Get-Content]、ParameterBindingException
    + FullyQualifiedErrorId : AmbiguousParameter,Microsoft.PowerShell.Commands.GetContentCommand

PS C:\PS_Work> cat test1.txt -Fir 1
This is test1 0 AAAA3,ABC,123,12345

-Delimiter で区切り文字を指定できます。ディフォルトでは改行が区切り文字です。

PS C:\PS_Work> cat test1.txt -Delimiter ','
This is test1 0 AAAA3,
ABC,
123,
12345
This is line 2 of test1 1 bbbb3,
2222,
33333
This is line 3 test1 2 CCCC3
This is line 4 test1 3 dddd3,
3333,
4444,
55555

Get-Date 現在の日付と時刻を取得する

Get-Date は、現在の日付と時刻を取得します。

DisplayHint 表示する要素を指定します。 Date 日付のみ表示 Time 時刻のみ表示  DateTime 日付と時刻を表示

PS C:\ps_work> Get-Date -DisplayHint Date

2022年11月16日

PS C:\ps_work> Get-Date -DisplayHint Time

23:03:05

PS C:\ps_work> Get-Date -DisplayHint DateTime

2022年11月16日 23:03:12

-DisplayHint は、デフォルトでは DateTime になっています。

PS C:\ps_work> Get-Date

2022年11月16日 23:06:01

PS C:\ps_work> Get-Date | Format-List

DisplayHint : DateTime
Date        : 2022/11/16 0:00:00
Day         : 16
DayOfWeek   : Wednesday
DayOfYear   : 320
Hour        : 23
Kind        : Local
Millisecond : 787
Minute      : 6
Month       : 11
Second      : 34
Ticks       : 638042367947873098
TimeOfDay   : 23:06:34.7873098
Year        : 2022
DateTime    : 2022年11月16日 23:06:34

-Format 表示するフォーマットを指定します。 

指定子定義
dddd曜日 – フル ネーム
MM月の番号
dd月の日 – 2 桁
yyyy4 桁の形式の年
HH:mm24 時間形式の時刻 -秒なし
K世界時座標 (UTC) からのタイム ゾーン オフセット
PS C:\ps_work> Get-Date -Format "MM/dd dddd HH:mm"
11/16 水曜日 23:12

PS C:\ps_work> Get-Date -Format "MM/dd/yyyy HH:mm"
11/16/2022 23:12

PS C:\ps_work> Get-Date -Format "MM/dd/yyyy HH:mm K"
11/16/2022 23:13 +09:00

PS C:\ps_work> Get-Date -Format "MM/dd/yyyy dddd HH:mm K"
11/16/2022 水曜日 23:13 +09:00

-Date 表示する日付と時刻を設定します。現在の日付と時刻を表示せずに、設定した日付と時刻を表示します。”01/01/2000 00:00:00″ のフォーマットで設定します。日付のみの指定、時刻のみの指定も出来ます。 -Format で曜日を表示すれば、その日が何曜日になるか、何曜日だったかを知ることが出来ます。

PS C:\ps_work> Get-Date -Date "12/31/2022 23:59:59"
2022年12月31日 23:59:59

PS C:\ps_work> Get-Date -Date "12/31/2022 23:59:59" -Format "MM/dd/yyyy dddd HH:mm"
12/31/2022 土曜日 23:59

PS C:\ps_work> Get-Date -Date "12/31/2022" -Format "MM/dd/yyyy dddd HH:mm"
12/31/2022 土曜日 00:00

PS C:\ps_work> Get-Date -Date "00:00:00" -Format "yyyy年MM月dd日 dddd HH時mm分"
2022年11月16日 水曜日 00時00分

Select-String ファイル内のテキストを検索する

エイリアスは、 sls です。

PS C:\PS_Work> Get-Alias -Definition Select-String

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Alias           sls -> Select-String

Select-String は、文字列とファイル内のテキストを検索します。

-Pattern で検索する文字列を指定します。 -Pattern は省略可能です。ディフォルトでは大文字、小文字は区別されません。

PS C:\PS_Work> cat test1.txt
This is test1 0 AAAA3,ABC,123,12345
This is line 2 of test1 1 bbbb3,2222,33333
This is line 3 test1 2 CCCC3
This is line 4 test1 3 dddd3,3333,4444,55555

PS C:\PS_Work> Select-String -Pattern 222 test1.txt

test1.txt:2:This is line 2 of test1 1 bbbb3,2222,33333


PS C:\PS_Work> Select-String abc test1.txt

test1.txt:1:This is test1 0 AAAA3,ABC,123,12345

上記のようにファイル指定して実行すると、アウトプットの先頭にファイル名と行数が出力されます。

パイプラインで入力を受けるとファイル名、行数は入りません。

PS C:\PS_Work> cat test1.txt | Select-String -Pattern 222

This is line 2 of test1 1 bbbb3,2222,33333

-NotMatch で文字列が含まれない項目を出力します。 -NotMatch は -n まで省略可能です。

PS C:\PS_Work> cat test1.txt | Select-String -NotMatch abc

This is line 2 of test1 1 bbbb3,2222,33333
This is line 3 test1 2 CCCC3
This is line 4 test1 3 dddd3,3333,4444,55555


PS C:\PS_Work> cat test1.txt | Select-String -n abc

This is line 2 of test1 1 bbbb3,2222,33333
This is line 3 test1 2 CCCC3
This is line 4 test1 3 dddd3,3333,4444,55555

-CaseSensitive 大文字、小文字を区別したい時に指定します。

PS C:\PS_Work> cat test2.txt | Select-String -Pattern This

This is test2 0 AAAA3,ABC,123,12345
this is line 2 of test2 1 bbbb3,2222,33333
this is line 3 test2 2 CCCC3
This is line 4 test2 3 dddd3,3333,4444,55555


PS C:\PS_Work> cat test2.txt | Select-String -Pattern This -CaseSensitive

This is test2 0 AAAA3,ABC,123,12345
This is line 4 test2 3 dddd3,3333,4444,55555

-Context 一致した前後の行を表示します。 次の例では -Context 1,2 で一致した行に “>” を表示し、前1行、後ろ2行を表示します。

PS C:\PS_Work> cat test3.txt
This is test3 0 AAAA3,ABC,123,12345
This is line2 of test3 1 bbbb3,2222,33333
This is line3 test3 2 CCCC3, Match
This is line4 test3 3 dddd3,3333,Match,4444,55555
This is line5 test3 3 dddd3,3333,4444,55555
This is line6 test3 3 dddd3,3333,4444,55555
This is line7 test3 3 dddd3,3333,4444,55555

PS C:\PS_Work> cat test3.txt | Select-String -Pattern match -context 1,2

  This is line2 of test3 1 bbbb3,2222,33333
> This is line3 test3 2 CCCC3, Match
> This is line4 test3 3 dddd3,3333,Match,4444,55555
  This is line5 test3 3 dddd3,3333,4444,55555
  This is line6 test3 3 dddd3,3333,4444,55555

Set-Location 現在の作業場所を指定された場所に設定します。

Change Directoryと同じ働きをしますが、ディレクトリ名に Squire Brackets [] 等の特殊文字があるとコマンドプロンプトの時のようには動きません 。特殊文字があるときは、パス指定に -LiteralPath を指定します。

PS >Get-Item CLIMAX*
    ディレクトリ: W:\
Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----        2021/09/16      9:36                CLIMAX BEST 歌謡曲 [ Disk 1 ]
d-----        2021/09/16      9:36                CLIMAX Best 歌謡曲 [ Disk 2 ]

-Path では見つからない。

PS >Set-Location -Path 'CLIMAX BEST 歌謡曲 [ Disk 1 ]'
Set-Location : パス 'CLIMAX BEST 歌謡曲 [ Disk 1 ]' が存在しないため検出できません。
発生場所 行:1 文字:1
+ Set-Location -Path 'CLIMAX BEST 歌謡曲 [ Disk 1 ]'
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

-LiteralPath を指定します。

PS >Set-Location -LiteralPath 'CLIMAX BEST 歌謡曲 [ Disk 1 ]'
PS >pwd
Path
----
W:\CLIMAX BEST 歌謡曲 [ Disk 1 ]

Out-String 入力オブジェクトをストリングに変換する

オブジェクトの入力を文字列に変換します。 -Stream パラメータを使用することにより一行づつ処理することが出来ます。 Out-String -Stream は、短縮形 OSS でパイプラインで使用されます。

次の例では、Get-ChildItem の出力を Select-String で test の文字列が含まれるアイテムだけを出力したいのですが、Get-ChildItem の出力はオブジェクトのため、Out-String -Stream で 一行の文字列に変換してから、Select-String で test の文字列が含まれる行だけを出力しています。

PS C:\PS_work> Get-ChildItem

    ディレクトリ: C:\PS_work

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----        2022/11/13     18:09                work1
d-----        2022/11/13     17:57                work2
d-----        2022/11/10     16:07                work3
-a----        2022/11/14     11:55           2276 Add-Signature.ps1
-a----        2022/11/14     12:03           3552 Get-MP3MetaData_LocalMade.ps1
-a----        2022/11/11      0:40             32 KanjiCopy.txt
-a----        2022/11/11     10:17             34 kanjiTest.txt
-a----        2022/11/10     15:53             72 test.txt
-a----        2022/11/10     18:52            158 test1.txt
-a----        2022/11/11      0:17            634 Test1Copy.txt
-a----        2022/11/10     19:12            158 test2.txt
-a----        2022/11/10     23:07            306 test3.txt
-a----        2022/11/10     23:21            311 test4.txt
-a----        2022/11/11     10:30             18 TestDesu.txt
-a----        2022/11/13     13:10            228 TestSort.txt
-a----        2022/11/13     13:52             94 TestSort2.txt

PS C:\PS_work> Get-ChildItem | OSS | Select-String -Pattern test

-a----        2022/11/11     10:17             34 kanjiTest.txt
-a----        2022/11/10     15:53             72 test.txt
-a----        2022/11/10     18:52            158 test1.txt
-a----        2022/11/11      0:17            634 Test1Copy.txt
-a----        2022/11/10     19:12            158 test2.txt
-a----        2022/11/10     23:07            306 test3.txt
-a----        2022/11/10     23:21            311 test4.txt
-a----        2022/11/11     10:30             18 TestDesu.txt
-a----        2022/11/13     13:10            228 TestSort.txt
-a----        2022/11/13     13:52             94 TestSort2.txt

Out-File ファイルに書き出す

Out-File のエイリアスはありません。

Out-File は、出力をファイルに書き出します。

PS C:\PS_Work> cat test1.txt | Out-File Test1Copy.txt

PS C:\PS_Work> cat Test1Copy.txt

This is test1 0 AAAA3,ABC,123,12345
This is line 2 of test1 1 bbbb3,2222,33333
This is line 3 test1 2 CCCC3
This is line 4 test1 3 dddd3,3333,4444,55555

-NoClobber ファイルが既に存在する場合、上書きを防ぎます。

PS C:\PS_Work> cat test1.txt | Out-File Test1Copy.txt -NoClobber
Out-File : ファイル 'C:\PS_Work\Test1Copy.txt' は既に存在します。
発生場所 行:1 文字:17
+ cat test1.txt | Out-File Test1Copy.txt -NoClobber
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ResourceExists: (C:\PS_Work\Test1Copy.txt:String) [Out-File], IOException
    + FullyQualifiedErrorId : NoClobber,Microsoft.PowerShell.Commands.OutFileCommand

-Append 既存のファイルの末尾に出力を追加します。

PS C:\PS_Work> cat test2.txt | Out-File Test1Copy.txt -Append

PS C:\PS_Work> cat Test1Copy.txt
This is test1 0 AAAA3,ABC,123,12345
This is line 2 of test1 1 bbbb3,2222,33333
This is line 3 test1 2 CCCC3
This is line 4 test1 3 dddd3,3333,4444,55555
This is test2 0 AAAA3,ABC,123,12345
this is line 2 of test2 1 bbbb3,2222,33333
this is line 3 test2 2 CCCC3
This is line 4 test2 3 dddd3,3333,4444,55555

-Width 書き出すファイルの行の長さを指定します。

長い行のテキストファイルを Get-Content で取得して、Select-String で抽出し Out-File で書き出すという処理をした場合、その時のPowerShell の画面が狭くてテキストファイルの行より短れば、以下のように書き出されたファイルのテキストは、画面の幅で改行されたものになってしまいます。これを防ぐために -width で書き出すファイルの行幅を指定します。

PS >cat 長い行.txt | sls "決済"  | Out-File 狭い画面.txt
PS >cat 狭い画面.txt
"AUD/JPY","買","決済","1","93.888","130","0","130","2022/11/26 01:16:41","2022/11/26 01:16:41"
,"126000007726405","-","0","\130"
"AUD/JPY","売","決済","1","93.934","30","0","30","2022/11/26 01:12:06","2022/11/26 01:12:06","
126000007726300","-","0","\30"
"AUD/JPY","買","決済","1","93.902","80","0","80","2022/11/26 01:09:59","2022/11/26 01:09:59","
126000007726224","-","0","\80"

同じ画面サイズで -Width 180 を指定して実行しました。

PS >cat 長い行.txt | sls "決済"  | Out-File 狭い画面width指定.txt -Width 180
PS >cat 狭い画面width指定.txt

"AUD/JPY","買","決済","1","93.888","130","0","130","2022/11/26 01:16:41","2022/11/26 01:16:41","126000007726405","-","0","\130"
"AUD/JPY","売","決済","1","93.934","30","0","30","2022/11/26 01:12:06","2022/11/26 01:12:06","126000007726300","-","0","\30"
"AUD/JPY","買","決済","1","93.902","80","0","80","2022/11/26 01:09:59","2022/11/26 01:09:59","126000007726224","-","0","\80"

Write-OutPut パイプラインに書き込む、コンソールに書き込む

エイリアスは echo , write の二つです。

PS C:\ps_work> get-alias -Definition write-output

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Alias           echo -> Write-Output
Alias           write -> Write-Output

Write-OutPut は、指定したオブジェクトをパイプラインに書き込みます。

PS C:\ps_work> Write-Output 'Testです' | Out-File TestDesu.txt

PS C:\ps_work> cat TestDesu.txt
Testです

Add-Content ファイルに追加する

エイリアスは ac です。

PS C:\ps_work> get-alias -Definition add-content

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Alias           ac -> Add-Content

Add-Content は、前述の Out-File -Append と同じ動きをします。

PS C:\ps_work> cat kanjitest.txt
漢字です。

PS C:\ps_work> write-output 'Test です' | Add-Content KanjiTest.txt

PS C:\ps_work> cat kanjitest.txt
漢字です。
Test です

PS C:\ps_work> write-output 'Test です' | Add-Content KanjiTest.txt

PS C:\ps_work> cat kanjitest.txt
漢字です。
Test です
Test です

Get-ChildItem ディレクトリの内容を取得する

エイリアスは、dir , gci , ls の三つが充てられています。

PS C:\ps_work> get-alias -definition get-childitem

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Alias           dir -> Get-ChildItem
Alias           gci -> Get-ChildItem
Alias           ls -> Get-ChildItem

Get-ChildItem は、ディレクトリの内容を取得します。

-Path でディレクトリを指定します。 -Path は省略できます。

PS C:\> Get-ChildItem  -Path \PS_Work

    ディレクトリ: C:\PS_Work

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----        2022/11/10     16:07                work1
d-----        2022/11/10     16:07                work2
d-----        2022/11/10     16:07                work3
-a----        2022/11/11      0:40             32 KanjiCopy.txt
-a----        2022/11/11     10:17             34 kanjiTest.txt
-a----        2022/11/10     15:53             72 test.txt
-a----        2022/11/10     18:52            158 test1.txt
-a----        2022/11/11      0:17            634 Test1Copy.txt
-a----        2022/11/10     19:12            158 test2.txt
-a----        2022/11/10     23:07            306 test3.txt
-a----        2022/11/10     23:21            311 test4.txt
-a----        2022/11/11     10:30             18 TestDesu.txt

-Recurse でサブディレクトリも取得します。空のディレクトリは表示しません。

PS C:\> Get-ChildItem  -Path \PS_Work -Recurse

    ディレクトリ: C:\PS_Work

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----        2022/11/10     16:07                work1
d-----        2022/11/10     16:07                work2
d-----        2022/11/10     16:07                work3
-a----        2022/11/11      0:40             32 KanjiCopy.txt
-a----        2022/11/11     10:17             34 kanjiTest.txt
-a----        2022/11/10     15:53             72 test.txt
-a----        2022/11/10     18:52            158 test1.txt
-a----        2022/11/11      0:17            634 Test1Copy.txt
-a----        2022/11/10     19:12            158 test2.txt
-a----        2022/11/10     23:07            306 test3.txt
-a----        2022/11/10     23:21            311 test4.txt
-a----        2022/11/11     10:30             18 TestDesu.txt

    ディレクトリ: C:\PS_Work\work1

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----        2022/11/10     15:53             72 test.txt

Rename-Item Itemの名前を変更する

エイリアスは、ren , rni です。

PS >Get-Alias -Definition Rename-Item

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Alias           ren -> Rename-Item
Alias           rni -> Rename-Item

Rename-Item -Path ‘アイテム名’ -NewName ‘新しいアイテム名’

-Path -NewName は、省略できます。

アイテム名は、ファイル名でもディレクトリ名でも変更します。

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----        2022/11/08     17:45                September
-a----        2022/11/26      2:07           5511 TradeRecordList (12).csv

PS >ren 'TradeRecordList (12).csv' 'TradeRecordList(12).csv'
d-----        2022/11/08     17:45                September
-a----        2022/11/26      2:07           5511 TradeRecordList(12).csv

PS >ren  'September' 'sep'
d-----        2022/11/08     17:45                sep
-a----        2022/11/26      2:07           5511 TradeRecordList(12).csv

Replace 置換演算子と組み合わせてあるパターンをまとめて変更出来ます。次の例は、ファイル名の中のスペースを削除しています。

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----        2022/11/26      2:07           5511 TradeRecordList (12).csv
-a----        2022/10/16     22:44          12510 TradeRecordList (13).csv
-a----        2022/10/16     22:44          12637 TradeRecordList (14).csv
-a----        2022/10/16     22:44          12536 TradeRecordList (15).csv
-a----        2022/10/16     22:45          12512 TradeRecordList (16).csv
-a----        2022/10/16     22:45          12513 TradeRecordList (17).csv
-a----        2022/10/16     22:47           7502 TradeRecordList (18).csv
-a----        2022/11/26      2:09           5517 TradeRecordList (20).csv
-a----        2022/11/26      2:09          12644 TradeRecordList (21).csv
-a----        2022/11/26      2:08          12633 TradeRecordList (22).csv
-a----        2022/11/26      2:08          12637 TradeRecordList (23).csv
-a----        2022/11/26      2:08          12588 TradeRecordList (24).csv
-a----        2022/11/26      2:08          12486 TradeRecordList (25).csv
-a----        2022/12/07     11:30          11714 TradeRecordList (26).csv

PS >Get-Item Trade*.csv | Rename-Item -NewName { $_.Name -replace ' ','' }

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----        2022/11/26      2:07           5511 TradeRecordList(12).csv
-a----        2022/10/16     22:44          12510 TradeRecordList(13).csv
-a----        2022/10/16     22:44          12637 TradeRecordList(14).csv
-a----        2022/10/16     22:44          12536 TradeRecordList(15).csv
-a----        2022/10/16     22:45          12512 TradeRecordList(16).csv
-a----        2022/10/16     22:45          12513 TradeRecordList(17).csv
-a----        2022/10/16     22:47           7502 TradeRecordList(18).csv
-a----        2022/11/26      2:09           5517 TradeRecordList(20).csv
-a----        2022/11/26      2:09          12644 TradeRecordList(21).csv
-a----        2022/11/26      2:08          12633 TradeRecordList(22).csv
-a----        2022/11/26      2:08          12637 TradeRecordList(23).csv
-a----        2022/11/26      2:08          12588 TradeRecordList(24).csv
-a----        2022/11/26      2:08          12486 TradeRecordList(25).csv
-a----        2022/12/07     11:30          11714 TradeRecordList(26).csv

アイテム名に特殊文字 Squire Brackets [] があるときは、.Replace(“`[","").Replace("`]”,””) で取り除けます。

PS >ls climax*
    ディレクトリ: W:\
Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----        2021/09/16      9:36                CLIMAX BEST 歌謡曲 [ Disk 1 ]
d-----        2021/09/16      9:36                CLIMAX Best 歌謡曲 [ Disk 2 ]
PS >Get-Item CLIMAX* | Rename-Item -NewName { $_.Name.Replace("`[","").Replace("`]","") }
PS >ls climax*
    ディレクトリ: W:\
Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
d-----        2021/09/16      9:36                CLIMAX BEST 歌謡曲  Disk 1
d-----        2021/09/16      9:36                CLIMAX Best 歌謡曲  Disk 2

ForEach-Object 各入力オブジェクトに対して操作を実行する

エイリアスは、 % です。

ForEach-Object は、各入力オブジェクト毎にスクリプト・ブロックで指示された操作を実行します。

以下の例では、文字列を “,” で区切って ForEach-Object でそれぞれの3文字目からを抽出しています。

PS C:\PS_work> "1 Apple,2 Banana,3 Strawberry,4 Orange,5 Cherry" -Split ","
1 Apple
2 Banana
3 Strawberry
4 Orange
5 Cherry
PS C:\PS_work> "1 Apple,2 Banana,3 Strawberry,4 Orange,5 Cherry" -Split "," | ForEach-Object { $_.Substring(2) }
Apple
Banana
Strawberry
Orange
Cherry

ForEach-Object では複数のスクリプト・ブロックを実行します。最初のスクリプトブロック { ‘begin’ }は、一番最初だけ実行、最後の { ‘end’ } は、最後だけ実行され、間のスクリプト・ブロックは毎回実行されます。

PS C:\PS_work> 1..10 | ForEach-Object { 'begin'  } { "$_" + 'process1' } {"$_" + "process2"} { 'end' }
begin
1process1
1process2
2process1
2process2
3process1
3process2
4process1
4process2
5process1
5process2
6process1
6process2
7process1
7process2
8process1
8process2
9process1
9process2
10process1
10process2
end

Format-List オブジェクトのプロパティをリスト形式で表示する

エイリアスは、 fl です。

Format-List は、オブジェクト形式の入力をプロパティごとにリストします。

PowerShell のコマンドレットの出力は、殆どの場合がオブジェクトです。オブジェクト形式の出力をパイプラインで受け取ってオブジェクトのプロパティのリストを表示します。

次の例では Get-ChildItem の出力をリスト形式で表示しています。

PS C:\PS_work\work1> Get-ChildItem

    ディレクトリ: C:\PS_work\work1

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----        2022/11/11     12:20              2 test.log
-a----        2022/11/10     15:53             72 test.txt

PS C:\PS_work\work1> Get-ChildItem | Format-List

    ディレクトリ: C:\PS_work\work1

Name           : test.log
Length         : 2
CreationTime   : 2022/11/11 12:20:50
LastWriteTime  : 2022/11/11 12:20:50
LastAccessTime : 2022/11/11 12:20:50
Mode           : -a----
LinkType       :
                 InternalName:
                 OriginalFilename:
                 FileVersion:
                 FileDescription:
                 Product:
                 ProductVersion:
                 Debug:            False
                 Patched:          False
                 PreRelease:       False
                 PrivateBuild:     False
                 SpecialBuild:     False
                 Language:


Name           : test.txt
Length         : 72
CreationTime   : 2022/11/10 16:07:33
LastWriteTime  : 2022/11/10 15:53:59
LastAccessTime : 2022/11/10 16:07:33
Mode           : -a----
LinkType       :
Target         : {}
VersionInfo    : File:             C:\PS_work\work1\test.txt
                 InternalName:
                 OriginalFilename:
                 FileVersion:
                 FileDescription:
                 Product:
                 ProductVersion:
                 Debug:            False
                 Patched:          False
                 PreRelease:       False
                 PrivateBuild:     False
                 SpecialBuild:     False
                 Language:

Select-Object オブジェクト、オブジェクトのプロパティ を選択する

エイリアスは、select です。

Select-Object は、オブジェクト、またはオブジェクトのプロパティを選択します。

-Property プロパティを指定して選択します。 次の例では、Select-String の出力には先頭にファイル名、行番号が出ています。ここから Select-Object -Property Line でプロパティの Line だけを選択しています。

PS C:\PS_work> Select-String -Pattern ABC -Path .\test*.txt

test.txt:1:abcdefg,ABC,123,12345
test1.txt:1:This is test1 0 AAAA3,ABC,123,12345
Test1Copy.txt:1:This is test1 0 AAAA3,ABC,123,12345
Test1Copy.txt:5:This is test2 0 AAAA3,ABC,123,12345
test2.txt:1:This is test2 0 AAAA3,ABC,123,12345
test3.txt:1:This is test3 0 AAAA3,ABC,123,12345
test4.txt:1:This is test4 0 AAAA3,ABC,123,12345

PS C:\PS_work> Select-String -Pattern ABC -Path .\test*.txt | Select-Object -Property Line

Line
----
abcdefg,ABC,123,12345
This is test1 0 AAAA3,ABC,123,12345
This is test1 0 AAAA3,ABC,123,12345
This is test2 0 AAAA3,ABC,123,12345
This is test2 0 AAAA3,ABC,123,12345
This is test3 0 AAAA3,ABC,123,12345
This is test4 0 AAAA3,ABC,123,12345

-First , -Last 先頭または末尾から取得するオブジェクトの数を指定できます。

PS C:\PS_work> Select-String -Pattern ABC -Path .\test*.txt | Select-Object -First 3

test.txt:1:abcdefg,ABC,123,12345
test1.txt:1:This is test1 0 AAAA3,ABC,123,12345
Test1Copy.txt:1:This is test1 0 AAAA3,ABC,123,12345


PS C:\PS_work> Select-String -Pattern ABC -Path .\test*.txt | Select-Object -Last 3

test2.txt:1:This is test2 0 AAAA3,ABC,123,12345
test3.txt:1:This is test3 0 AAAA3,ABC,123,12345
test4.txt:1:This is test4 0 AAAA3,ABC,123,12345

-Skip 先頭から除外したいオブジェクトの数を指定できます。

PS C:\PS_work> Select-String -Pattern ABC -Path .\test*.txt | Select-Object -Property Line -Skip 1

Line
----
This is test1 0 AAAA3,ABC,123,12345
This is test1 0 AAAA3,ABC,123,12345
This is test2 0 AAAA3,ABC,123,12345
This is test2 0 AAAA3,ABC,123,12345
This is test3 0 AAAA3,ABC,123,12345
This is test4 0 AAAA3,ABC,123,12345

-Index インデックスで指定したオブジェクトだけ選択します。インデックスは、0から始まります。

PS C:\PS_work> Select-String -Pattern ABC -Path .\test*.txt | Select-Object -Property Line

Line
----
abcdefg,ABC,123,12345
This is test1 0 AAAA3,ABC,123,12345
This is test1 0 AAAA3,ABC,123,12345
This is test2 0 AAAA3,ABC,123,12345
This is test2 0 AAAA3,ABC,123,12345
This is test3 0 AAAA3,ABC,123,12345
This is test4 0 AAAA3,ABC,123,12345

PS C:\PS_work> Select-String -Pattern ABC -Path .\test*.txt | Select-Object  -Property Line | Select-Object -Index 0,3

Line
----
abcdefg,ABC,123,12345
This is test2 0 AAAA3,ABC,123,12345

Sort-Object オブジェクトのプロパティの値でオブジェクトを並べ変える

簡単なアンケートに答えるだけでポイントが貯まる!貯まったポイントは現金や電子マネーに交換可能♪

エイリアスは、 sort です。

Sort-Object は、指定されたプロパティの値でオブジェクトを並び変えます。

-Property プロパティを指定します。次の例では、Get-ChildItem でディレクトリの内容を取得し、プロパティ Length で並び変えて容量の少ない順に表示しています。-Property は省略できます。

PS C:\ps_work> Get-ChildItem | Sort-Object -Property Length

    ディレクトリ: C:\ps_work

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----        2022/11/11     10:30             18 TestDesu.txt
-a----        2022/11/11      0:40             32 KanjiCopy.txt
-a----        2022/11/11     10:17             34 kanjiTest.txt
-a----        2022/11/10     15:53             72 test.txt
-a----        2022/11/10     18:52            158 test1.txt
-a----        2022/11/10     19:12            158 test2.txt
-a----        2022/11/10     23:07            306 test3.txt
-a----        2022/11/10     23:21            311 test4.txt
-a----        2022/11/11      0:17            634 Test1Copy.txt
-a----        2022/11/11     22:36           1455 Get-MP3MetaData.ps1
d-----        2022/11/11     12:20                work1
d-----        2022/11/10     16:07                work3
d-----        2022/11/10     16:07                work2

次の例では、ファイルの内容を並べ変え表示しています。

PS C:\ps_work> Get-Content TestSort.txt
ZZZZZZZZZZZZZZ
SSSSSSSSSSSSSS
AAAAAAAAAAAAAA
DDDDDDDDDDDDDDD
KKKKKKKKKKKKKK
UUUUUUUUUUUUUUU
BBBBBBBBBBBBBB
qqqqqqqqqqqqqq
wwwwwwwwwwwwww
dddddddddddddd
wwwwwwwwwwWWWW
PS C:\ps_work> Get-Content TestSort.txt | Sort-Object
AAAAAAAAAAAAAA
BBBBBBBBBBBBBB
dddddddddddddd
DDDDDDDDDDDDDDD
KKKKKKKKKKKKKK
qqqqqqqqqqqqqq
SSSSSSSSSSSSSS
UUUUUUUUUUUUUUU
wwwwwwwwwwwwww
wwwwwwwwwwWWWW
ZZZZZZZZZZZZZZ

-Descending 降順に並び変えます。

PS C:\ps_work> Get-ChildItem | Sort-Object Length -Descending

    ディレクトリ: C:\ps_work

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----        2022/11/11     22:36           1455 Get-MP3MetaData.ps1
-a----        2022/11/11      0:17            634 Test1Copy.txt
-a----        2022/11/10     23:21            311 test4.txt
-a----        2022/11/10     23:07            306 test3.txt
-a----        2022/11/10     19:12            158 test2.txt
-a----        2022/11/10     18:52            158 test1.txt
-a----        2022/11/10     15:53             72 test.txt
-a----        2022/11/11     10:17             34 kanjiTest.txt
-a----        2022/11/11      0:40             32 KanjiCopy.txt
-a----        2022/11/11     10:30             18 TestDesu.txt
d-----        2022/11/11     12:20                work1
d-----        2022/11/10     16:07                work2
d-----        2022/11/10     16:07                work3

-Unique ソートした結果から重複を排除します。

PS C:\ps_work> Get-Content TestSort2.txt
bbbbbbbbb1
AAAAAAAAA2
AAAAAAAAA1
BBBBBBBBB1
ccccccccc1
CCCCCCCCC1
AAAAAAAAA1
aaaaaaaaa2
PS C:\ps_work> Get-Content TestSort2.txt | Sort-Object -Unique
AAAAAAAAA1
aaaaaaaaa2
bbbbbbbbb1
CCCCCCCCC1

-CaseSensitive 大文字・小文字を区別します。

PS C:\ps_work> Get-Content TestSort2.txt | Sort-Object -Unique
AAAAAAAAA1
aaaaaaaaa2
bbbbbbbbb1
CCCCCCCCC1
PS C:\ps_work> Get-Content TestSort2.txt | Sort-Object -Unique -CaseSensitive
AAAAAAAAA1
aaaaaaaaa2
AAAAAAAAA2
bbbbbbbbb1
BBBBBBBBB1
ccccccccc1
CCCCCCCCC1

Set-ExecutionPolicy スクリプトの実行ポリシーを変更する

PowerShell のスクリプトは、実行ポリシーにより実行出来るかどうかが決められています。実行ポリシーを設定していない状態では、通常、Undefined の状態です。 Undefined は Restricted と判断され、スクリプトは実行出来ません。

次の例は、実行ポリシーがUndefinedの状態でスクリプトを実行しようとした時の結果です。

PS C:\ps_work> ./Get-MP3MetaData.ps1  w:\Carpenters | select -f 1
./Get-MP3MetaData.ps1 : このシステムではスクリプトの実行が無効になっているため、ファイル C:\ps_work\Get-MP3MetaData.ps1 を読み込むことができません。詳細については、「about_Execution_Policies」(https://go.microso
ft.com/fwlink/?LinkID=135170) を参照してください。
発生場所 行:1 文字:1
+ ./Get-MP3MetaData.ps1  w:\Carpenters | select -f 1
+ ~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : セキュリティ エラー: (: ) []、PSSecurityException
    + FullyQualifiedErrorId : UnauthorizedAccess

現状の実行ポリシーは、 Get-ExecutionPolicy -List で知ることが出来ます。

PS C:\ps_work> Get-ExecutionPolicy -List

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process       Undefined
  CurrentUser       Undefined
 LocalMachine       Undefined

実行ポリシーには、次の種類があります。

  • Unrestricted    
  • RemoteSigned   
  • AllSigned
  • Restricted     
  • Default       
  • Bypass       
  • Undefined     

実行ポリシーの変更は、PowerShellを管理者として実行し、 Set-ExecutionPolicy コマンドレットで設定します。

実行ポリシー Unrestricted

すべてのスクリプトを実行します。インターネットからダウンロードしたスクリプト、リモートコンピュータにあるスクリプトを実行する時は警告プロンプトがでます。

PS C:\WINDOWS\system32> Set-ExecutionPolicy Unrestricted

実行ポリシーの変更
実行ポリシーは、信頼されていないスクリプトからの保護に役立ちます。実行ポリシーを変更すると、about_Execution_Policies
のヘルプ トピック (https://go.microsoft.com/fwlink/?LinkID=135170)
で説明されているセキュリティ上の危険にさらされる可能性があります。実行ポリシーを変更しますか?
[Y] はい(Y)  [A] すべて続行(A)  [N] いいえ(N)  [L] すべて無視(L)  [S] 中断(S)  [?] ヘルプ (既定値は "N"): Y

PS C:\WINDOWS\system32> Get-ExecutionPolicy -List

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process       Undefined
  CurrentUser       Undefined
 LocalMachine    Unrestricted

次の例は、GitHubから入手したMP3のメタデータを取得するスクリプトの実行結果です。

./Get-MP3Metadata_LocalMade.ps1 は、ダウンロードしたスクリプトからマニュアルで行をコピーしたローカルメイドのスクリプトです。

.\work1/Get-MP3Metadata.ps1 は、ダウンロードしたままのスクリプトです。

W:\Get-MP3MetaData_LocalMade.ps1 ドライブ W: は自宅設置のNASコンピュータです。

これらのスクリプトにはどれもデジタル署名はされていません。

次の例では、ローカルで作ったスクリプトは何も警告なしで実行されています。

PS C:\ps_work> ./Get-MP3Metadata_LocalMade.ps1 w:\carpenters | select -f 1

アルバム         : TWENTY-TWO HITS OF THE CARPENTERS
タイトル         : I NEED TO BE IN LOVE
名前             : 01 I NEED TO BE IN LOVE.mp3
サイズ           : 3.51 MB
参加アーティスト : THE CARPENTERS
年               : 1995
長さ             : 00:03:50
ビット レート    : ‎128kbps
評価             : 評価なし
ジャンル         : Pop
作成者           : THE CARPENTERS
項目の種類       : MP3 ファイル
Directory        : w:\carpenters
Fullname         : W:\carpenters\01 I NEED TO BE IN LOVE.mp3
Extension        : .mp3

インターネットからダウンロードしたスクリプトは、実行前に警告がでます。

PS C:\ps_work> .\work1/Get-MP3Metadata.ps1 w:\carpenters | select -f 1

セキュリティ警告
信頼するスクリプトのみを実行してください。インターネットから入手したスクリプトは便利ですが、コンピューターに危害を及ぼす可能性があります。このスクリプトを信頼する場合は、この警告メッセージが表示さ
れないように、Unblock-File コマンドレットを使用して、スクリプトの実行を許可してください。C:\ps_work\work1\Get-MP3MetaData.ps1 を実行しますか?
[D] 実行しない(D)  [R] 一度だけ実行する(R)  [S] 中断(S)  [?] ヘルプ (既定値は "D"): R

アルバム         : TWENTY-TWO HITS OF THE CARPENTERS
タイトル         : I NEED TO BE IN LOVE
名前             : 01 I NEED TO BE IN LOVE.mp3
サイズ           : 3.51 MB
参加アーティスト : THE CARPENTERS
年               : 1995
長さ             : 00:03:50
ビット レート    : ‎128kbps
評価             : 評価なし
ジャンル         : Pop
作成者           : THE CARPENTERS
項目の種類       : MP3 ファイル
Directory        : w:\carpenters
Fullname         : W:\carpenters\01 I NEED TO BE IN LOVE.mp3
Extension        : .mp3

リモートに置いたスクリプトは、実行前に警告が出ます。

PS C:\ps_work> W:\Get-MP3MetaData_LocalMade.ps1 w:\carpenters | select -f 1

セキュリティ警告
信頼するスクリプトのみを実行してください。インターネットから入手したスクリプトは便利ですが、コンピューターに危害を及ぼす可能性があります。このスクリプトを信頼する場合は、この警告メッセージが表示さ
れないように、Unblock-File コマンドレットを使用して、スクリプトの実行を許可してください。W:\Get-MP3MetaData_LocalMade.ps1 を実行しますか?
[D] 実行しない(D)  [R] 一度だけ実行する(R)  [S] 中断(S)  [?] ヘルプ (既定値は "D"): R

アルバム         : TWENTY-TWO HITS OF THE CARPENTERS
タイトル         : I NEED TO BE IN LOVE
名前             : 01 I NEED TO BE IN LOVE.mp3
サイズ           : 3.51 MB
参加アーティスト : THE CARPENTERS
年               : 1995
長さ             : 00:03:50
ビット レート    : ‎128kbps
評価             : 評価なし
ジャンル         : Pop
作成者           : THE CARPENTERS
項目の種類       : MP3 ファイル
Directory        : w:\carpenters
Fullname         : W:\carpenters\01 I NEED TO BE IN LOVE.mp3
Extension        : .mp3
Unblock-File インターネットからダウンロードされたファイルのブロックを解除する
会員数は国内最大級の180万人を突破!【paters】

Unblock-File でブロックを解除すると警告が出なくなります。

PS C:\ps_work> Unblock-File .\work1\Get-MP3MetaData.ps1
PS C:\ps_work> .\work1/Get-MP3Metadata.ps1 w:\carpenters | select -f 1

アルバム         : TWENTY-TWO HITS OF THE CARPENTERS
タイトル         : I NEED TO BE IN LOVE
名前             : 01 I NEED TO BE IN LOVE.mp3
サイズ           : 3.51 MB
参加アーティスト : THE CARPENTERS
年               : 1995
長さ             : 00:03:50
ビット レート    : ‎128kbps
評価             : 評価なし
ジャンル         : Pop
作成者           : THE CARPENTERS
項目の種類       : MP3 ファイル
Directory        : w:\carpenters
Fullname         : W:\carpenters\01 I NEED TO BE IN LOVE.mp3
Extension        : .mp3

実行ポリシー RemoteSigned

リモートコンピュータにあるスクリプトはデジタル署名されている必要があります。インターネットからダウンロードしたスクリプトもデジタル署名されている必要があります。ローカルにあるスクリプトは実行できます。

PS C:\WINDOWS\system32> Set-ExecutionPolicy RemoteSigned

実行ポリシーの変更
実行ポリシーは、信頼されていないスクリプトからの保護に役立ちます。実行ポリシーを変更すると、about_Execution_Policies
のヘルプ トピック (https://go.microsoft.com/fwlink/?LinkID=135170)
で説明されているセキュリティ上の危険にさらされる可能性があります。実行ポリシーを変更しますか?
[Y] はい(Y)  [A] すべて続行(A)  [N] いいえ(N)  [L] すべて無視(L)  [S] 中断(S)  [?] ヘルプ (既定値は "N"): Y

PS C:\WINDOWS\system32> Get-ExecutionPolicy -List

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process       Undefined
  CurrentUser       Undefined
 LocalMachine    RemoteSigned

ローカルで作ったローカルコンピュータにあるスクリプトは実行できます。

PS C:\ps_work> ./Get-MP3Metadata_LocalMade.ps1 w:\carpenters | select -f 1

アルバム         : TWENTY-TWO HITS OF THE CARPENTERS
タイトル         : I NEED TO BE IN LOVE
名前             : 01 I NEED TO BE IN LOVE.mp3
サイズ           : 3.51 MB
参加アーティスト : THE CARPENTERS
年               : 1995
長さ             : 00:03:50
ビット レート    : ‎128kbps
評価             : 評価なし
ジャンル         : Pop
作成者           : THE CARPENTERS
項目の種類       : MP3 ファイル
Directory        : w:\carpenters
Fullname         : W:\carpenters\01 I NEED TO BE IN LOVE.mp3
Extension        : .mp3

インターネットからダウンロードしたスクリプトでデジタル署名されていないものは実行できません。

PS C:\ps_work> .\work1/Get-MP3Metadata.ps1 w:\carpenters | select -f 1
.\work1/Get-MP3Metadata.ps1 : ファイル C:\ps_work\work1\Get-MP3MetaData.ps1 を読み込めません。ファイル C:\ps_work\work1\Get-MP3MetaData.ps1 はデジタル署名されていません。このスクリプトは現在のシス
テムでは実行できません。スクリプトの実行および実行ポリシーの設定の詳細については、「about_Execution_Policies」(https://go.microsoft.com/fwlink/?LinkID=135170) を参照してください。
発生場所 行:1 文字:1
+ .\work1/Get-MP3Metadata.ps1 w:\carpenters | select -f 1
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : セキュリティ エラー: (: ) []、PSSecurityException
    + FullyQualifiedErrorId : UnauthorizedAccess

インターネットからダウンロードして Unblock-File でブロック解除したものは実行できます。

PS C:\ps_work> Unblock-File .\work1\Get-MP3MetaData.ps1

PS C:\ps_work> .\work1/Get-MP3Metadata.ps1 w:\carpenters | select -f 1


アルバム         : TWENTY-TWO HITS OF THE CARPENTERS
タイトル         : I NEED TO BE IN LOVE
名前             : 01 I NEED TO BE IN LOVE.mp3
サイズ           : 3.51 MB
参加アーティスト : THE CARPENTERS
年               : 1995
長さ             : 00:03:50
ビット レート    : ‎128kbps
評価             : 評価なし
ジャンル         : Pop
作成者           : THE CARPENTERS
項目の種類       : MP3 ファイル
Directory        : w:\carpenters
Fullname         : W:\carpenters\01 I NEED TO BE IN LOVE.mp3
Extension        : .mp3

リモートにあるスクリプトは、デジタル署名がなければ実行されません。

PS C:\ps_work> W:\Get-MP3MetaData_LocalMade.ps1 w:\carpenters | select -f 1
W:\Get-MP3MetaData_LocalMade.ps1 : ファイル W:\Get-MP3MetaData_LocalMade.ps1 を読み込めません。ファイル W:\Get-MP3MetaData_LocalMade.ps1 はデジタル署名されていません。このスクリプトは現在のシステム
では実行できません。スクリプトの実行および実行ポリシーの設定の詳細については、「about_Execution_Policies」(https://go.microsoft.com/fwlink/?LinkID=135170) を参照してください。
発生場所 行:1 文字:1
+ W:\Get-MP3MetaData_LocalMade.ps1 w:\carpenters | select -f 1
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : セキュリティ エラー: (: ) []、PSSecurityException
    + FullyQualifiedErrorId : UnauthorizedAccess

実行ポリシー AllSigned

すべてのスクリプトは、デジタル署名がされている必要があります。

PS C:\WINDOWS\system32> Set-ExecutionPolicy AllSigned

実行ポリシーの変更
実行ポリシーは、信頼されていないスクリプトからの保護に役立ちます。実行ポリシーを変更すると、about_Execution_Policies
のヘルプ トピック (https://go.microsoft.com/fwlink/?LinkID=135170)
で説明されているセキュリティ上の危険にさらされる可能性があります。実行ポリシーを変更しますか?
[Y] はい(Y)  [A] すべて続行(A)  [N] いいえ(N)  [L] すべて無視(L)  [S] 中断(S)  [?] ヘルプ (既定値は "N"): Y

PS C:\WINDOWS\system32> Get-ExecutionPolicy -List

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process       Undefined
  CurrentUser       Undefined
 LocalMachine       AllSigned

ローカルにあっても、Unblock-File されていても、デジタル署名のないものは実行出来ません。

PS C:\ps_work> ./Get-MP3Metadata_LocalMade.ps1 w:\carpenters | select -f 1
./Get-MP3Metadata_LocalMade.ps1 : ファイル C:\ps_work\Get-MP3MetaData_LocalMade.ps1 を読み込めません。ファイル C:\ps_work\Get-MP3MetaData_LocalMade.ps1 はデジタル署名されていません。このスクリプト
は現在のシステムでは実行できません。スクリプトの実行および実行ポリシーの設定の詳細については、「about_Execution_Policies」(https://go.microsoft.com/fwlink/?LinkID=135170) を参照してください。
発生場所 行:1 文字:1
+ ./Get-MP3Metadata_LocalMade.ps1 w:\carpenters | select -f 1
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : セキュリティ エラー: (: ) []、PSSecurityException
    + FullyQualifiedErrorId : UnauthorizedAccess
PS C:\ps_work> .\work1/Get-MP3Metadata.ps1 w:\carpenters | select -f 1
.\work1/Get-MP3Metadata.ps1 : ファイル C:\ps_work\work1\Get-MP3MetaData.ps1 を読み込めません。ファイル C:\ps_work\work1\Get-MP3MetaData.ps1 はデジタル署名されていません。このスクリプトは現在のシス
テムでは実行できません。スクリプトの実行および実行ポリシーの設定の詳細については、「about_Execution_Policies」(https://go.microsoft.com/fwlink/?LinkID=135170) を参照してください。
発生場所 行:1 文字:1
+ .\work1/Get-MP3Metadata.ps1 w:\carpenters | select -f 1
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : セキュリティ エラー: (: ) []、PSSecurityException
    + FullyQualifiedErrorId : UnauthorizedAccess
PS C:\ps_work> W:\Get-MP3MetaData_LocalMade.ps1 w:\carpenters | select -f 1
W:\Get-MP3MetaData_LocalMade.ps1 : ファイル W:\Get-MP3MetaData_LocalMade.ps1 を読み込めません。ファイル W:\Get-MP3MetaData_LocalMade.ps1 はデジタル署名されていません。このスクリプトは現在のシステム
では実行できません。スクリプトの実行および実行ポリシーの設定の詳細については、「about_Execution_Policies」(https://go.microsoft.com/fwlink/?LinkID=135170) を参照してください。
発生場所 行:1 文字:1
+ W:\Get-MP3MetaData_LocalMade.ps1 w:\carpenters | select -f 1
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : セキュリティ エラー: (: ) []、PSSecurityException
    + FullyQualifiedErrorId : UnauthorizedAccess
デジタル署名の仕方

スクリプトの署名方法については、こちらに書かれていますが、ちょっと工夫しないとうまく行きません。

自己署名証明書の作成

前述のマイクロソフトのリンク先の自己証明書の作成を行います。PowerShell のコンソールで次のテキストをキーインします。

$params = @{
    Subject = 'CN=PowerShell Code Signing Cert'
    Type = 'CodeSigning'
    CertStoreLocation = 'Cert:\CurrentUser\My'
    HashAlgorithm = 'sha256'
}
$cert = New-SelfSignedCertificate @params

自己証明書が出来たかどうかを次のコマンドで確認します。

PS C:\WINDOWS\system32> Get-ChildItem cert:\CurrentUser\my -codesigning

   PSParentPath: Microsoft.PowerShell.Security\Certificate::CurrentUser\my

Thumbprint                                Subject
----------                                -------
E9CFE893468A1BB65575A084D4F5978A4B95D866  CN=PowerShell Code Signing Cert
署名用スクリプトの記述

エディターで次のコードを記述して、 Add-Signature.ps1 というファイル名で UTF8 BOM無しのエンコードで保存します。

## Signs a file
param([string] $file=$(throw "Please specify a filename."))
$cert = @(Get-ChildItem cert:\CurrentUser\My -codesigning)[0]
Set-AuthenticodeSignature $file $cert
Add-Signature.ps1 に署名する

作成したスクリプト・ファイル ‘Add-Signature.ps1’ に署名するため、次のコマンドを入れます。

PS C:\PS_work> $cert = @(Get-ChildItem cert:\CurrentUser\My -codesigning)[0]
PS C:\PS_work> Set-AuthenticodeSignature add-signature.ps1 $cert

    ディレクトリ: C:\PS_work

SignerCertificate                         Status                                                Path
-----------------                         ------                                                ----
E9CFE893468A1BB65575A084D4F5978A4B95D866  UnknownError                                          add-signature.ps1

マイクロソフトのページでは、これでうまく行くように記述されていますが、実際はご覧のように Status UnknownError になってしまいます。

add-signature.ps1 を実行しようとすると、次の様なエラーになります。

PS C:\PS_work> ./add-signature.ps1
./add-signature.ps1 : ファイル C:\PS_work\Add-Signature.ps1 を読み込めません。証明書チェーンは処理されましたが、信頼プロバイダーが信頼していないルー
ト証明書で強制終了しました。。
発生場所 行:1 文字:1
+ ./add-signature.ps1
+ ~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : セキュリティ エラー: (: ) []、PSSecurityException
    + FullyQualifiedErrorId : UnauthorizedAccess

証明書チェーンは処理されましたが、信頼プロバイダーが信頼していないルート証明書で強制終了しました。。

こうなった場合は、次の処理が必要です。

作成した自己証明書を移動する

コマンド窓に ’証明書の管理’ と入れて出てきた ユーザー証明書の管理 をクリックします。

個人 – 証明書 の中の “PowerShell Code Signing Cert” を選択してマウスの右クリック -> 切り取り(T) をクリックします。

信頼されたルート証明機関 – 証明書 に 貼り付け(P) ます。

信頼されたルート証明機関 – 証明書 の中に入ったことを確認します。

PowerShell から証明書を確認

Get-ChildItem cert:\CurrentUser でユーザー証明書の格納場所が分かります。

PS C:\PS_work> Get-ChildItem cert:\CurrentUser

Name : TrustedPublisher
Name : ClientAuthIssuer
Name : McAfee Trust
Name : Root
Name : UserDS
Name : CA
Name : REQUEST
Name : AuthRoot
Name : TrustedPeople
Name : ADDRESSBOOK
Name : Local NonRemovable Certificates
Name : My
Name : SmartCardRoot
Name : Trust
Name : Disallowed

“PowerShell Code Signing Cert ” を移動した先の ”信頼されたルート証明機関” の格納場所は、 Root です。

Get-ChildItem cert:\CurrentUser\Root -codesigning でPowerShell Cord Signing Cert があるかどうか確認できます。

PS C:\PS_work> Get-ChildItem cert:\CurrentUser\Root -codesigning

   PSParentPath: Microsoft.PowerShell.Security\Certificate::CurrentUser\Root
Thumbprint                                Subject
----------                                -------
29820E024AE5BB72931778CDABA7990354581AD8  CN=PowerShell Code Signing Cert
信頼されたルート証明機関に移動した PowerShell Cord Signing Cert で署名する

次のコマンドで、信頼されたルート証明機関に移動した PowerShell Cord Signing Cert で ‘add-signature.ps1’ スクリプトに署名します。

$cert = @(Get-ChildItem cert:\CurrentUser\Root -codesigning)[0]

Set-AuthenticodeSignature add-signature.ps1 $cert

PS C:\PS_work> $cert = @(Get-ChildItem cert:\CurrentUser\Root -codesigning)[0]
PS C:\PS_work> Set-AuthenticodeSignature add-signature.ps1 $cert

    ディレクトリ: C:\PS_work

SignerCertificate                         Status                                                Path
-----------------                         ------                                                ----
29820E024AE5BB72931778CDABA7990354581AD8  Valid                                                 add-signature.ps1

無事に署名されました。

add-signature.ps1 のコードも Root の中の証明書を使うように次のように変更します。

## Signs a file
param([string] $file=$(throw "Please specify a filename."))
$cert = @(Get-ChildItem cert:\CurrentUser\Root -codesigning)[0]
Set-AuthenticodeSignature $file $cert

Add-Signature.ps1 で Get-MP3MetaData_LocalMade.ps1 に署名します。

PS C:\PS_work> ./Add-Signature.ps1 Get-MP3MetaData_LocalMade.ps1

    ディレクトリ: C:\PS_work

SignerCertificate                         Status                                                Path
-----------------                         ------                                                ----
29820E024AE5BB72931778CDABA7990354581AD8  Valid                                                 Get-MP3MetaData_LocalMade.ps1

実行ポリシー AllSigned で 実行出来るか 確認します。

PS > Get-ExecutionPolicy -List

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process       Undefined
  CurrentUser       Undefined
 LocalMachine       AllSigned

PS C:\PS_work> ./Get-MP3MetaData_LocalMade.ps1 w:\k.工藤静香 | select -Ind 5

アルバム         : 工藤静香ベスト
タイトル         :  くちびるから媚薬
名前             : 工藤静香 -  くちびるから媚薬.mp3
サイズ           : 3.65 MB
参加アーティスト : 工藤静香
年               : 1990
長さ             : 00:03:56
ビット レート    : ‎128kbps
評価             : 評価なし
ジャンル         : J ポップ
作成者           : 工藤静香
項目の種類       : MP3 ファイル
Directory        : w:\k.工藤静香
Fullname         : w:\k.工藤静香\工藤静香 -  くちびるから媚薬.mp3
Extension        : .mp3

実行ポリシー Restricted

スクリプトの実行は出来ません。既定値です。

PS > Set-ExecutionPolicy Restricted

実行ポリシーの変更
実行ポリシーは、信頼されていないスクリプトからの保護に役立ちます。実行ポリシーを変更すると、about_Execution_Policies のヘルプ トピック
(https://go.microsoft.com/fwlink/?LinkID=135170) で説明されているセキュリティ上の危険にさらされる可能性があります。実行ポリシーを変更しますか?
[Y] はい(Y)  [A] すべて続行(A)  [N] いいえ(N)  [L] すべて無視(L)  [S] 中断(S)  [?] ヘルプ (既定値は "N"): Y

PS C:\PS_work> Get-ExecutionPolicy -List

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process       Undefined
  CurrentUser       Undefined
 LocalMachine      Restricted

どんなスクリプトも実行出来ません。

PS > ./Get-MP3MetaData_LocalMade.ps1 w:\k.工藤静香 | select -Ind 5
./Get-MP3MetaData_LocalMade.ps1 : このシステムではスクリプトの実行が無効になっているため、ファイル C:\PS_work\Get-MP3MetaData_LocalMade.ps1 を読み込
むことができません。詳細については、「about_Execution_Policies」(https://go.microsoft.com/fwlink/?LinkID=135170) を参照してください。
発生場所 行:1 文字:1
+ ./Get-MP3MetaData_LocalMade.ps1 w:\k.工藤静香 | select -Ind 5
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : セキュリティ エラー: (: ) []、PSSecurityException
    + FullyQualifiedErrorId : UnauthorizedAccess

実行ポリシー Default

簡単なアンケートに答えるだけでポイントが貯まる!貯まったポイントは現金や電子マネーに交換可能♪

既定の実行ポリシーを設定します。既定値は、Restricted です。

PS > Set-ExecutionPolicy Default

実行ポリシーの変更
実行ポリシーは、信頼されていないスクリプトからの保護に役立ちます。実行ポリシーを変更すると、about_Execution_Policies のヘルプ トピック
(https://go.microsoft.com/fwlink/?LinkID=135170) で説明されているセキュリティ上の危険にさらされる可能性があります。実行ポリシーを変更しますか?
[Y] はい(Y)  [A] すべて続行(A)  [N] いいえ(N)  [L] すべて無視(L)  [S] 中断(S)  [?] ヘルプ (既定値は "N"): Y

PS > Get-ExecutionPolicy -List

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process       Undefined
  CurrentUser       Undefined
 LocalMachine      Restricted

実行ポリシー Bypass

何もブロックされず、警告やプロンプトは出ません。

PS > Set-ExecutionPolicy Bypass

実行ポリシーの変更
実行ポリシーは、信頼されていないスクリプトからの保護に役立ちます。実行ポリシーを変更すると、about_Execution_Policies のヘルプ トピック
(https://go.microsoft.com/fwlink/?LinkID=135170) で説明されているセキュリティ上の危険にさらされる可能性があります。実行ポリシーを変更しますか?
[Y] はい(Y)  [A] すべて続行(A)  [N] いいえ(N)  [L] すべて無視(L)  [S] 中断(S)  [?] ヘルプ (既定値は "N"): Y

PS C:\PS_work> Get-ExecutionPolicy -List

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process       Undefined
  CurrentUser       Undefined
 LocalMachine          Bypass

リモートの署名なしのスクリプトも何も警告なしで実行します。

PS > ls w:\get*

    ディレクトリ: w:\

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----        2022/11/13     14:29           1458 Get-MP3MetaData_LocalMade.ps1
-a----        2022/11/13     14:29           1458 Get-MP3MetaData.ps1

PS > w:\Get-MP3MetaData_LocalMade.ps1 W:\ABBA | select -f 1

ジャンル         : Pop
タイトル         : Dancing Queen
名前             : 01 Dancing Queen.mp3
サイズ           : 4.39 MB
参加アーティスト : Abba
長さ             : 00:03:50
ビット レート    : ‎160kbps
評価             : 評価なし
作成者           : Abba
項目の種類       : MP3 ファイル
Directory        : W:\ABBA
Fullname         : w:\ABBA\01 Dancing Queen.mp3
Extension        : .mp3

PS > w:\Get-MP3MetaData.ps1 W:\ABBA | select -Ind 1

ジャンル         : Pop
タイトル         : Angeleyes
名前             : 02 Angeleyes.mp3
サイズ           : 4.98 MB
参加アーティスト : Abba
長さ             : 00:04:21
ビット レート    : ‎160kbps
評価             : 評価なし
作成者           : Abba
項目の種類       : MP3 ファイル
Directory        : W:\ABBA
Fullname         : w:\ABBA\02 Angeleyes.mp3
Extension        : .mp3

実行ポリシー Undefined

実行ポリシーが設定されていない状態です。Restricted とみなされます。

PS > Set-ExecutionPolicy Undefined

実行ポリシーの変更
実行ポリシーは、信頼されていないスクリプトからの保護に役立ちます。実行ポリシーを変更すると、about_Execution_Policies のヘルプ トピック
(https://go.microsoft.com/fwlink/?LinkID=135170) で説明されているセキュリティ上の危険にさらされる可能性があります。実行ポリシーを変更しますか?
[Y] はい(Y)  [A] すべて続行(A)  [N] いいえ(N)  [L] すべて無視(L)  [S] 中断(S)  [?] ヘルプ (既定値は "N"): Y
PS C:\PS_work> Get-ExecutionPolicy -List

        Scope ExecutionPolicy
        ----- ---------------
MachinePolicy       Undefined
   UserPolicy       Undefined
      Process       Undefined
  CurrentUser       Undefined
 LocalMachine       Undefined

PS C:\PS_work> Get-ExecutionPolicy
Restricted

Test-Path ファイルの存在を調べる

Test-Path は、ファイルの存在を調べて、存在する場合はTrue を返します。

$FileName = ".\MixedChartOfTrade.HTML"
if (Test-Path $FileName ) {
  Remove-Item $FileName
}

よく使う関数、演算子、メソッド

PowerShell のプロンプトの変更

PowerShell を起動すると ”PS C:\Users\xxxx” の様なプロンプトが出ますが、これを変更することができます。

これは、Prompt() 関数によりディフォルトで “PS Current_Directory>” を出すように設定されているからです。

Function Prompt() を書き換えることにより、このプロンプトを変更することができます。

PS C:\Users\Xxxxx> cd \ps_work
PS C:\ps_work>
PS C:\ps_work>
PS C:\ps_work>
PS C:\ps_work> Function Prompt() { "PS>" }
PS>
PS>

Profile.PS1 の記述

上記のPrompt の変更などPowerShell を立ち上げる度に入力するのは、手間ですのでプロファイルに設定しておけば一々入力しなくて済みます。プロファイルは、 C:\Windows\Windowspowershell\V1.0 のディレクトリに Profile.PS1 というファイルを置くことで設定できます。PowerShell を管理者で立ち上げて次の様に Profile.PS1 を “C:\Windows\Windowspowershell\V1.0” に記述します。

PS C:\WINDOWS\system32> cd WindowsPowerShell
PS C:\WINDOWS\system32\WindowsPowerShell> cd V1.0
PS C:\WINDOWS\system32\WindowsPowerShell\V1.0> "Function Prompt() { ""PS >"" }" | Add-Content Profile.PS1
PS C:\WINDOWS\system32\WindowsPowerShell\V1.0> ls p*

    ディレクトリ: C:\WINDOWS\system32\WindowsPowerShell\V1.0

Mode                 LastWriteTime         Length Name
----                 -------------         ------ ----
-a----        2021/09/16      1:58         452608 powershell.exe
-a----        2019/12/07     18:10            395 powershell.exe.config
-a----        2019/12/07     18:10         206468 PowerShellCore.format.ps1xml
-a----        2019/12/07     18:10           4097 PowerShellTrace.format.ps1xml
-a----        2019/12/07      2:05         212992 powershell_ise.exe
-a----        2019/10/15     22:50            465 powershell_ise.exe.config
-a----        2022/11/25     12:32             30 Profile.PS1
-a----        2019/12/07     18:10          55808 PSEvents.dll
-a----        2019/12/07     18:09         174592 pspluginwkr.dll
-a----        2019/12/07     18:10           2560 pwrshmsg.dll
-a----        2021/09/16      1:58          30720 pwrshsip.dll

Substring メソッド 文字列から部分文字列の抽出

文字列.Substring(開始位置,文字数) で 文字列から文字列を切り出すことが出来ます。開始位置は ‘ 0 ‘ から始まります。

PS > "ABCDEFGHIJK".Substring(0,3)
ABC

PS > "ABCDEFGHIJK".Substring(3,4)
DEFG

$() 部分式演算子

PowerShellでは「$( )」で括った式を「部分式演算子」と言います。 部分式演算子は「()」内の文を評価した結果を返します。文字列の中に部分式演算子を入れることにより、文字列の中に式の結果を出力できます。

PS > get-date -format "MM/dd"
11/16

PS > "Today is $(get-date -format "MM/dd")"
Today is 11/16

Split 演算子 文字列を分割する

文字列 -Split ‘区切り文字’  または 文字列.Split (‘区切り文字’) で文字列を区切り文字で分割します。

PS > "1111,2222,3333,4444,5555,6666" -Split','
1111
2222
3333
4444
5555
6666
PS > "1111,2222,3333,4444,5555,6666".Split(',')
1111
2222
3333
4444
5555
6666

Max-substrings 文字列 -Split ‘区切り文字’,n n で分割する最大数を指定します。 

PS > "111 1222 2333 3444 4555 56666" -Split' ',3
111
1222
2333 3444 4555 56666

ピリオド (.) を区切り文字としたい場合、 文字列 -Split “.” とするとうまく行きません。

PS > "1111.2222.3333.4444.5555" -Split "."




ピリオド (.) を区切り文字としたい場合は、文字列.Split(“.”) とします。または、文字列 -Split “\.” でも 

PS > "1111.2222.3333.4444.5555".Split(".")
1111
2222
3333
4444
5555
PS C:\PS_work> "1111.2222.3333.4444.5555" -Split "\."
1111
2222
3333
4444
5555

複数の区切り文字を使いたい時は、 パイプラインで繋げて ForEach-Object で処理します。

PS > "1111 2222,3333.4444 5555,6666" -Split "\." | % { $_ -Split "," } | % { $_ -Split " " }
1111
2222
3333
4444
5555
6666

Count 演算子

要素の数をカウントします。 (文字列,変数,変数).Count で()内の要素の数を返します。

(文字列.Split(“文字”)).Count – 1 で、文字列の中の文字の数を得る事ができます。

PS >("2022/12/01".Split("/")).Count - 1
2
PS >("2022/12/01-2022/12/31".Split("/")).Count - 1
4

Replace 置換演算子

‘インプット文字列’ -replace ‘検索文字列’ , ‘置換文字列’     インプット文字列の中の検索文字列を置換文字列に置き換えます。

PS >'ABCDEFG HIJUKLM' -replace 'ABCD' , '1234'
1234EFG HIJUKLM

.. 範囲演算子

1..10 のように数字と数字の間にピリオドを二つ置くと、範囲演算子になります。 1..10 では、 1から10までの数字を順に出力します。

PS> 1..10
1
2
3
4
5
6
7
8
9
10

パイプラインでWhere-Object や ForEach-Object に渡すことにより、いろいろな操作が可能です。

奇数を出力

PS> 1..10 | Where-Object { $_ % 2 }
1
3
5
7
9

偶数を出力

PS> 1..10 | Where-Object { $_ % 2 -1 }
2
4
6
8
10

10 づつ出力

PS >1..10 | % { $_ * 10 }
10
20
30
40
50
60
70
80
90
100

2 のべき乗(平方根)を出力

PS > 1..10 | % { [Math]::Pow(2, $_) }
2
4
8
16
32
64
128
256
512
1024

1~12 を英語の3文字表記で出力します。

PS >$us = New-Object system.globalization.cultureinfo("en-US")
PS >1..12 | % { (Get-Date -Date "$($_)/01").ToString("MMM",$us) }
Jan
Feb
Mar
Apr
May
Jun
Jul
Aug
Sep
Oct
Nov
Dec

配列変数の定義

PowerShellでは、変数の定義は必要ありませんが、配列変数にいきなりインデックスを付けての指定は出来ません。

PS >$StrArray[0] = "ABC"
null 配列にインデックスを付けることはできません。
発生場所 行:1 文字:1
+ $StrArray[0] = "ABC"
+ ~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) []、RuntimeException
    + FullyQualifiedErrorId : NullArray

範囲演算子で予め代入しておくことで、配列変数として定義されます。

PS >$StrArray = 1..9
PS >$StrArray[0]
1
PS >$StrArray[8]
9
PS >$StrArray[0] = "ABC"
PS >$StrArray[8] = "XYZ"
PS >$StrArray[0]
ABC
PS >$StrArray[8]
XYZ

マルチ・ディメンジョンの配列

3x3 や 9x9 のマルチディメンジョンの配列は範囲演算子を複数代入することにより作ることが出来ます。

PS >$mdarray = (1..3),(1..3),(1..3)
PS >$mdarray[0][0]
1
PS >$mdarray[2][2]
3
PS >$mdarray
1
2
3
1
2
3
1
2
3

ToCharArray() メソッド 文字列を一文字づつ配列に代入

String.ToCharArray() でString文字列を一文字づつ Array に代入します。

PS >$Mojiretsu = "ABCDEFG"
PS >$MojiArray = $Mojiretsu.ToCharArray()
PS >$MojiArray
A
B
C
D
E
F
G
PS >$MojiArray[0]
A
PS >$MojiArray[6]
G

ToCharArray() で代入した配列変数には、以後も一文字しか代入出来ません。

PS >$mojiArray[0]
A
PS >$mojiArray[0] = "ABC"
値 "ABC" を型 "System.Char" に変換できません。エラー: "String には一文字しか使用できません。"
発生場所 行:1 文字:1
+ $mojiArray[0] = "ABC"
+ ~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) []、RuntimeException
    + FullyQualifiedErrorId : InvalidCastParseTargetInvocation

複数の変数にまとめて代入も出来ます。

PS >$Memo = "123"
PS >$n1,$n2,$n3 = $Memo.ToCharArray()
PS >$n1
1
PS >$n2
2
PS >$N3
3

応用編、およびスクリプト

CSV ファイルのある条件の行を抽出する

次のような内容のCSVファイルから項目10番目の日付が 08/12 ~ 08/15 のものを抽出します。

"CAD/JPY","買","決済","1","104.917","-190","0","-190","2022/08/10 05:42:46","2022/08/10 05:42:46"
"CAD/JPY","売","決済","1","104.914","40","210","250","2022/08/10 08:57:23","2022/08/10 08:57:23"
"CAD/JPY","売","決済","1","104.061","-5,780","0","-5,780","2022/08/12 01:21:10","2022/08/12 01:21:10"
"CAD/JPY","買","決済","1","104.276","-2,250","-146","-2,396","2022/08/15 10:42:57","2022/08/15 10:42:57"
"AUD/JPY","売","決済","1","94.563","-3,170","374","-2,796","2022/08/23 22:45:03","2022/08/23 22:45:03"
"AUD/JPY","買","決済","1","94.521","960","0","960","2022/08/23 23:01:27","2022/08/23 23:01:27"

Import-Csv 抽出Test.csv -Header H1,H2,H3,H4,H5,H6,H7,H8,H9,H10 | Where-Object { $_.H10 -GT “2022/08/12” } | Where-Object { $_.H10 -LT “2022/08/16” }

Import-Csv で 各項目に H1 ~ H10 のプロパティ名を付けて読み込みます。 Where-Object で プロパティH10 の内容が “2022/08/12″ より大きい行、および ”2022/08/16” より小さい行を抜き出します。

PS > Import-Csv 抽出Test.csv -Header H1,H2,H3,H4,H5,H6,H7,H8,H9,H10 | Where-Object { $_.H10 -GT "2022/08/12" } | Where-Object { $_.H10 -LT "2022/08/16" }


H1  : CAD/JPY
H2  : 売
H3  : 決済
H4  : 1
H5  : 104.061
H6  : -5,780
H7  : 0
H8  : -5,780
H9  : 2022/08/12 01:21:10
H10 : 2022/08/12 01:21:10

H1  : CAD/JPY
H2  : 買
H3  : 決済
H4  : 1
H5  : 104.276
H6  : -2,250
H7  : -146
H8  : -2,396
H9  : 2022/08/15 10:42:57
H10 : 2022/08/15 10:42:57

アウトプットがオブジェクトなので上記の様な形式で表示されます。 ConvertTo-Csv で変換すると

PS > Import-Csv 抽出Test.csv -Header H1,H2,H3,H4,H5,H6,H7,H8,H9,H10 | Where-Object { $_.H10 -GT "2022/08/12" } | Where-Object { $_.H10 -LT "2022/08/16" } | ConvertTo-Csv
#TYPE System.Management.Automation.PSCustomObject
"H1","H2","H3","H4","H5","H6","H7","H8","H9","H10"
"CAD/JPY","売","決済","1","104.061","-5,780","0","-5,780","2022/08/12 01:21:10","2022/08/12 01:21:10"
"CAD/JPY","買","決済","1","104.276","-2,250","-146","-2,396","2022/08/15 10:42:57","2022/08/15 10:42:57"

また、Export-Csv 抽出結果.csv -Encoding UTF8 で CSV ファイルにアウトプットすることも出来ます。

与えられた期間指定の日付を判定するスクリプト

引数で与えられた期間を表す日付をどの様な形でも正しく処理するスクリプトを書いてみました。

以下のようないろいろなパターンを処理します。

  • 8/11-8/25            -> 開始日 2022/08/11 終了日 2022/08/25
  • 08/1-12/20           -> 開始日 2022/08/01 終了日 2022/12/20
  • 2022/01/01-10/1      -> 開始日 2022/01/01 終了日 2022/10/01
  • 1/1-2022/10/23       -> 開始日 2022/01/01 終了日 2022/10/23
  • 2022/10/23-02/14     -> 開始日 2022/10/23 終了日 2023/02/14
  • 11/03-02/12          -> 開始日 2021/11/03 終了日 2022/02/12
If ($Args[0].length -gt 5) {                                                # 5桁以上の引数がないときはスキップ
   $Start_YYYYMMDD,$End_YYYYMMDD = $Args[0].Split("-")                      # "-" でスプリットして開始月日と終了月日に分ける 
   $Start_Year = ""
   $End_Year = "" 
   $End_Day = ""
   if ( (($Start_YYYYMMDD.Split("/")).Count -1) -LT 2  ) {                  # 開始月日の中に / が2個以上あるか

      $Start_Mon,$Start_Day = $Start_YYYYMMDD.Split("/") }                  # 2個以上ないので 月と日に分ける

   else {

      $Start_Year,$Start_Mon,$Start_Day = $Start_YYYYMMDD.Split("/") }      # 2個以上なので 年と月と日に分ける

    if ( (($End_YYYYMMDD.Split("/")).Count -1) -LT 2 ) {          # 終了月日の中に / が2個以上あるか

      $End_Mon,$End_Day = $End_YYYYMMDD.Split("/");  }                      # 2個以上ないので 月と日に分ける

   else {
 
      $End_Year,$End_Mon,$End_Day = $End_YYYYMMDD.Split("/") }              # 2個以上なので 年と月と日に分ける
 
   if ( $End_Day.length -eq 0 ) {                                           # 月、日が1桁のときは頭に 0 をつける
 
      $End_Day = $End_Mon ; $End_Mon = $Start_Mon } 

   if ( $Start_Mon.length -lt 2 ) { 

      $Start_Mon = "0" + $Start_Mon }

   if ( $Start_Day.length -lt 2 ) { 

      $Start_Day = "0" + $Start_Day }

   if ( $End_Mon.length -lt 2 ) { 

      $End_Mon = "0" + $End_Mon }

   if ( $End_Day.length -lt 2 ) { 

      $End_Day = "0" + $End_Day }

   if ($End_Year -eq "" ) {                                                      # 終了年 未指定か?
      if ($Start_Year -ne "" ) {                                                   # yes 終了年 未指定, 開始年は指定されている?
         if ($End_Mon -LT $Start_Mon) {                                              # yes 開始年は指定, 終了月 < 開始月 年を跨ぐ
             $End_Year = "$([Int]$Start_Year + 1)"                                     # yes 年を跨ぐ, 終了年を開始年 + 1 に
             }                                                              
         else { $End_Year = $Start_Year                                                # no 年を跨がない, 終了年 = 開始年
             }                                
      }  
      else {  $End_Year = Get-Date -Format "yyyy"                                 # no 開始年 未指定,終了年 も指定なし 終了年を現在の年に
           if ($End_Mon -LT $Start_Mon) { $Start_Year = "$([Int]$End_Year - 1)"     # 年を跨いでいる?  yes 開始年 = 終了年 - 1
           }  
           else  { $Start_Year = $End_Year                                          # 年を跨がない 開始年 = 終了年
           }                                  
      }    
   }
   else {                                                                           # no 終了年 指定
        if ($Start_Year.length -eq 0 ) {                                               # 開始年 未指定か?
            if ($End_Mon -LT $Start_Mon) {  $Start_Year = "$([Int]$End_Year - 1)"      # yes 開始年未指定 , 年を跨いでいるか?  yes 開始年 = 終了年 - 1
               }
            else { $Start_Year = $End_Year                                                                           # no 年を跨がない 開始年 = 終了年
               }
        }
   }
   if ( $End_Year.length -lt 2 ) { 

      $End_Year = "0" + $End_Year }
   if ( $Start_Year.length -lt 2 ) { 

      $Start_Year = "0" + $Start_Year }

   If ($Start_Year.Length -LT 3 ) { $Start_Year = "20" + $Start_Year }         # 年が省略形のときは 20 を add
   If ($End_Year.Length -LT 3 ) { $End_Year = "20" + $End_Year  }
   $StartDay = $Start_Year + "/" + $Start_Mon + "/" + $Start_day
   $EndDay = $End_Year + "/" + $End_Mon + "/" + $End_Day

   }
else {
   $StartDay = ""
   $EndDay ="All Period"
}

   Write-Output $("開始日 " +  $StartDay)
   Write-Output $("終了日 " + $EndDay)

実行結果

PS >./TestDay.ps1 8/11-8/25
開始日 2022/08/11
終了日 2022/08/25
PS >
PS >./TestDay.ps1 08/1-12/20
開始日 2022/08/01
終了日 2022/12/20
PS >
PS >./TestDay.ps1 2022/01/01-10/1
開始日 2022/01/01
終了日 2022/10/01
PS >
PS >./TestDay.ps1 1/1-2022/10/23
開始日 2022/01/01
終了日 2022/10/23
PS >
PS >./TestDay.ps1 2022/10/23-02/14
開始日 2022/10/23
終了日 2023/02/14
PS >
PS >./TestDay.ps1 11/03-02/12
開始日 2021/11/03
終了日 2022/02/12

PowerShell から他のアプリケーションを実行する

パスが通っているアプリは直接入力すれば実行されます。

PS >notepad
PS >calc
PS >emeditor.exe

パスの通っていないアプリは、もちろん認識できないエラーになります。

PS >hello.exe
hello.exe : 用語 'hello.exe' は、コマンドレット、関数、スクリプト ファイル、または操作可能なプログラムの名前として認識
されません。名前が正しく記述されていることを確認し、パスが含まれている場合はそのパスが正しいことを確認してから、再試行
してください。

PS >sakura.exe
sakura.exe : 用語 'sakura.exe' は、コマンドレット、関数、スクリプト ファイル、または操作可能なプログラムの名前として認
識されません。名前が正しく記述されていることを確認し、パスが含まれている場合はそのパスが正しいことを確認してから、再試
行してください。

パスも含めて入力すれば実行できます。

PS >\newprog\hello.exe
こんにちは ワールド!

パスにスペースが含まれている場合は、正しく認識できないためエラーになります。

PS >C:\Program Files (x86)\sakura-tag-v2.4.1-build2849-ee8234f-Win32-Release-Exe\sakura.exe
x86 : 用語 'x86' は、コマンドレット、関数、スクリプト ファイル、または操作可能なプログラムの名前として認識されません。
名前が正しく記述されていることを確認し、パスが含まれている場合はそのパスが正しいことを確認してから、再試行してください
。

スペースが含まれているパスを ダブルクォーテーション ” で囲めば、実行できます。

PS >C:\"Program Files (x86)"\sakura-tag-v2.4.1-build2849-ee8234f-Win32-Release-Exe\sakura.exe

または、全体を ” で囲んで頭に & を付ければ実行されます。

PS >& "C:\Program Files (x86)\sakura-tag-v2.4.1-build2849-ee8234f-Win32-Release-Exe\sakura.exe"

実行されているPowerShellが管理者で実行されているかを外部から調べる

次のコマンドを記述したスクリプト .ps1 ファイルをコマンドプロンプトで実行します。

get-Process powershell | select MainWindowTitle

実行されているPowerShell window が 管理者モードの場合は次の表示

C:\vbs>powershell ./gptest.ps1

MainWindowTitle
---------------

管理者: Windows PowerShell

管理者モードでないときは、次の表示になります。

C:\vbs>powershell ./gptest.ps1

MainWindowTitle
---------------

Windows PowerShell

Visual Basic でPowerShell を使う

VBでPowerShell の スクリプトやコマンドレットを使うためには、

Imports System.Management.Automation を記述します。System.Management.Automation をインポートするためには、Project 参照の追加で、System.Management.Automation.dll を追加します。

参照の追加の仕方

ソリューション・エクスプローラでプロジェクトを右クリック–> 追加 –> プロジェクト参照 をクリックします。

参照マネージャーで参照をクリック

System.Management.Automation.dll の有るディレクトリへ移動し、選択して 追加をクリック

システムによって存在するディレクトリは違います。

OKをクリック

イククルはコチラ!(18禁) 老舗サイトのラブサーチ[18歳以上] 会員数は国内最大級の180万人を突破!【paters】

コメント

タイトルとURLをコピーしました