PowerShell（AD関連）

# コマンドまとめ

## `Get-ADUser`
**`Get-ADUser`はADユーザー情報を取得するコマンドレット**
```
Get-ADUser -Identity ＜ユーザーorアカウント名>
```
①特定ユーザーの基本情報を取得
```
Get-ADUser -Identity jdoe
```
②ユーザーの詳細情報（プロパティ）を取得
```
Get-ADUser -Identity jdoe -Properties *
```
③複数ユーザーをフィルタで取得（例：IT部門）
```
Get-ADUser -Filter "Department -eq `IT`" -Properties DisplayName,Title,Department
```
④ユーザー所属のグループを確認
```
Get-ADUser -Identity jdoe -Properties MemberOf ｜ Select-Object -ExpandProperty MemberOf
```
⑤属性を確認
```
Get-ADUser -Identity jdoe -Properties Mail,UserPrincipalName,DisplayName
```

## `Get-Content`
**ファイルの内容を取得するためのコマンドレット**
ログ解析や監視、場所指定してCSVに保存もできる
```
Get-Content -Path <ファイルパス>
```
①`C:⚪︎⚪︎`の内容を全て表示
```
Get-Content -Pach "C:⚪︎⚪︎"
```
②指定した行数だけ表示
```
Get-Content -Pach "C:⚪︎⚪︎" -TotalCount 10
```

## CSV
CSVに保存するためのコマンドレッド
```
Export-Csv -Path <ファイルパス> -NoTypeInformation
```
- `-Pach`:CSVファイルの保存先を指定
- `-NoTypeInformation`:不要な型情報を出力しない
- `-Append`:既存のCSVに追記する場合に使用
- `-Delimiter`:区切り文字を変更する場合に使用（`,`）

①例：ADユーザーの表示名、メール、部署をCSVに保存
```
Get-ADUser -Filter * -Properties DisplayName,Mail,Department ｜ Select-Object DisplayName,Mail,Department ｜ Export-Csv -Pach "C:⚪︎⚪︎.csv" -NoTypeInformation
```

:::note info
⭐️ **2回プロパティを定義する理由**
`-Properties`と`Select-Object`を同時に使う理由はデータの取得範囲を広げつつ最終的な出力を絞るため

- `Properties`
ADから必要なプロパティを取得する（データの取得）
- `Select-Object`
取得済みのプロパティから出力を絞り込む（画面やCSVへの表示）

⚠️`-Properties`だけの場合
- ADから`DisplayName`と`Mail`を取得するが大量のプロパティが一緒に返される（例えば`SID`や`ObjectGUID`など）
- 画面出力はデフォルトプロパティしか表示されないため取得されても見えない

⚠️`Select-Object`だけの場合
- `-Properties`を指定していないため`DisplayName`や`Mail`は取得されない
- 結果は空白（プロパティが`null`）になる

❗️つまり両方を組み合わせることで「必要なプロパティをADから取得」し、「画面やCSVに必要なものだけ出力」が可能になる！
:::



②ADFSログから"Error"を含む行を取得してCSVに保存
```
Get-Content -Pach "C:⚪︎⚪︎.log" ｜ Select-String "Error" ｜ ForEach-Object { [PSCustomObject]@{Line = $_} } ｜ Export-csv -Pach "C:⚪︎⚪︎.csv" -NoTypeInformation
```

:::note info

⭐️ **`{}`の使い方**
波かっこ、ブレーズという。
ブロックやスクリプトブロックを定義するために使う。処理をまとめたりフィルタ条件を書いたり繰り返し処理を行う際に重要

- `{}`で囲まれた部分は1つの「処理のかたまり（スクリプトブロック）」になる
- スクリプトブロックは変数に代入、呼び出し、ループや条件分岐で使用される

```
# スクリプトブロックを変数に代入
$myBlock = {
    Get-Date
    Write-Output "こんにちは！"
}

# 実行
& $myBlock
```

`{}`の行頭スペースはインデントという
コードを見やすく整理するための書式
特にネスト（入れ子）した時の階層構造が直感的に理解できエラーやロジックミスが減る。半角スペース4個が多くのプログラミング言語での標準となっている。`Tab`でインデントを作れることが多い。

:::

③ユーザー一覧を既存のCSVに追記する場合
```
Get-ADUser -Filter * -Properties DisplayName,Mail ｜ Select-Object DisplayName,Mail ｜ Export-Csv -Pach "C:⚪︎⚪︎.csv" -NoTypeInformation -Append
```

## `Select-Object`
PowerShellで取得したオブジェクトから必要なプロパティを選択するコマンドレッド。特に`Get-ADUser`や`Get-AdfsRelyingPartyTrust`などと組み合わせて必要な情報だけを絞り込んで出力するのに使用
```
<取得コマンド> ｜ Select-Object <プロパティ名1>,<プロパティ名2>,〜〜
```
- 不要なプロパティを除外し見やすい形式で出力できる
- エクスポート（`Export-Csv`）時の列選択としてもよく使う
- `-First`,`-Last`,`Unique`などで結果の絞り込みも可能

①ADFSのRelying Party Trustの名前と識別子だけを取得（特定プロパティを選択して表示）
```
Get-AdfsRelyingPartyTrust ｜ Select-Object Name,Identifier
```

②ADユーザーの表示名にエイリアスをつけて出力（プロパティにエイリアス（別名）をつける）
```
Get-ADUser -Filter * -Properties DisplayName,Mail ｜ Select-Object @{Name=`ユーザー名`;Expression={$_.DisplayName}},@{Name=`メールアドレス`;Expression={$_.Mail}}
```
:::note info
⭐️上記スクリプトの役割
- `@{}`
ハッシュテーブル（キーと値の組み合わせ）
簡単に言うと「設定をまとめるもの」
他に
    - `@()`：リストをまとめる
    - `{}`：処理をまとめる
という意味を持つものもある
- `Name = "..."`
表示する列名（エイリアス）を指定
- `Expression ={}`
プロパティや計算式をスクリプトブロックで記述
- `$_.`
現在処理中のオブジェクトのプロパティを参照
- `｜`
パイプライン、前の結果を後ろおコマンドに入力する
:::


③最初の10件だけ取得
```
Get-ADUser -Filter * ｜ Select-Ocject -First 10
```
④ADFS証明書の有効期限一覧を取得
```
Get-AdfsCertificate -CertificateType Token-Signing ｜ Select-Object subject, NotAfter
```
:::note info
- `Get-AdfsCertificate`
ADFSの証明書を取得するコマンドレット
- `-CertificateType Token-Signing`
「トークン署名用の証明書」だけを取得するためのオプション
- `Subject`
証明書の発行対象（CN＝）を表示
- `NotAfter`
証明書の有効期限（終了日時）を表示
:::

## `if`
条件に応じて異なる処理を実行するための基本構文
    `-gt`（より大きい）や`-eq`（等しい）など**比較演算子**というものが使われている
```
if(<条件式>) {
    <条件が真の場合の処理>
} elseif (<別の条件が真の場合の処理> {
    <別の条件が真の場合の処理>
} else {
    <全ての条件が偽の場合の処理>
}
```
①数値の比較
```
$number = 42

if ($number -gt 50) {
    Write-Output "50より大きい"
} elseif ($number -eq 42) {
    Write-Output "42に等しい"
} else {
    Write-Output "50以下"
}

# 結果
42に等しい
```

:::note info
⭐️`Write-Output`とは
値（オブジェクト）を出力するための基本コマンドレッド。簡単に言うと「結果を返す」もの。コンソールにメッセージを表示したりパイプラインで次のコマンドにデータを渡したりする役割も持っている。**尚、PowerShellでは`Write-Output`は省略可能！**`Write-Host`は画面にだけ直接出力しパイプには流れない

- 例：画面に文字を出力
```
Write-Output "こんにちは、PowerShell！"

# 結果
こんにちは、PowerShell!
```

- 例：`Write-Output`をパイプラインで繋げる
`Write-Output`は`Hello`をパイプラインに流し`Out-File`がその内容を`greeting.txt`に保存する
```
Write-Output "Hello" ｜ Out-FilePath "greeting.txt"
```

- 例：複数行をパイプラインで繋げてフィルターする
"Apple","Banana","Cherry"を`Write-Object`がパイプラインに送り`Where-Object`が「Bで始まるものだけを表示」する
```
Write-Output "Apple","Banana","Cherry" ｜ Where-Object {$_ -like "B*" }

# 結果
Banana
```

:::



②文字列の比較
```
$name = "Taro"

if ($name -eq "Taro") {
    Write-Output "こんにちは、Taroさん"
} else {
    Write-Output "あなたは誰ですか？"
}

# 結果
こんにちは、Taroさん
```
③ADFS証明書の有効期限を確認して報告
```
$cert = Get-AdfsCertificate -CertificateType Token-Signing
$today = Get-Date

if ($cert.NotAfter -It $today) {
    Write-Output "⚠️証明書が期限切れです！"
} elseif ($cert.NotAfter -It $today.AddDay(30)) {
    Write-Output "⚠️証明書の期限が30日以内に切れます。更新を検討してください。"
} else {
    Write-Output "✅証明書は有効です。"
}
```

## `Test`
何かを確認（テスト）する用途に使われる
- `Test-Connection`
接続の確認（ping相当）
- `Test-NetConnection`
ネットワーク接続・ポート開放の確認
- `Test-Path`
ファイルやフォルダの存在確認
- `Test-Command`
コマンドが存在するか確認
- `Test-Service`
サービスが稼働しているか確認（カスタム関数で実施）
- `Test-WSMan`
WinRMサービスが有効か確認
- `Test-IsAdministrator`
管理者権限で実行しているか確認（カスタム関数で実施）

**`Test`後のパラメータ**
- `-ComputerName`
接続先を指定（ホスト名・IPアドレス）
```
-ComputerName "192.168.1.10"
```

- `-Count`
パケット数を指定（既定は4回送信）
```
-Count 2
```

- `-Source`
送信元コンピュータを指定（リモート時用）
```
-Source "Server01"
```

- `-AsJob`
バックグラウンドジョブとして実行
- `Quiet`
応答があれば`True`、なければ`False`で返す

---


①ADFSサーバーのIPアドレス確認
```
Test-Connection -ComputerName "192.168.1.20" -Count 4
```
②複数のIPアドレスに対して接続確認（ループでまとめてチェック）
```
$ips = @("192.168.1.10", "192.168.1.11", "192.168.1.12")

foreach ($ip in $ips) {
    if (Test-Connection -ComputerName $ip -Count 2 -Quiet) {
    Write-Output "$ip は接続可能です✅"
    } else {
    Write-Output #$ip は接続できません❌"
    }
}
```

:::note info
- `foreach`とは
`foreach`の中で`$ips'に格納された配列から1つずつ値を受け取る変数。PowerShellが自動的に1つずつ`$ip`に代入しながらループを回す（名前が似てるのはたまたま。全くの別物。変数を`$ip`から`$item`などに変更してもOK
:::


## `Get`と`Test`の違い
- `Get-NetTCPConnection`
ローカルPCの通信セッション状況（リッスン状態など）を調査する
例：ローカルで443がLISTEN状態か確認
「ADFSがポート443で正常に起動しているか？」
```
Get-NetTCPConnection -LocalPost 443
```


- `Test-NetConnection`
指定先のネットワーク接続・ポート疎通を確認する（`ping`,`telnet`相当、`Test-NetConnection`は2つを統合したもの。2つと比べてコマンドレッドが長いが多機能）
例：ポート443でリモート接続テスト
「WAPからADFSサーバーへ接続できるのか？」
```
Test-NetConnection -ComputerName "⚪︎⚪︎.com" -Port443
```

- `ping`
ICMPプロトコルを使用してホストの「到達可否」だけを確認（ポートは確認不可）
- `telnet`
特定のTCPポートに