PowerShellのNew-Itemコマンド: 5つの具体的な利用例で理解するという問いには、既存TEMPを起点に、ディレクトリ、空ファイル、値入りファイル、リンク、レジストリキーのちょうど五例を別名で試すという方法で答えます。New-Itemの挙動はFileSystemやRegistryなどプロバイダーで異なる。親パスが存在することをTest-Pathで確認し、同名項目がある場合はForceで上書きせず例を止める。この記事では既に存在する$env:TEMPを親にし、各例のLiteralPath、ItemType、既存有無を個別に確認するを判断軸にし、実行前の確認、記事固有のコード、合否判定、戻し方を一続きで示します。
seq96の冪等な自動化パターンとは異なり、この記事は既存パス上でProvider差を学ぶ五例だけを提示する。完了は「五つそれぞれのProvider、ItemType、FullNameまたはPSPathが期待どおりで、既存項目を変更していない」と定義します。対象が取れない場合は「親パスやリンク先がなければその例だけを保留し、存在しないC:Ops等を前提にしない」として切り分け、推測で成功扱いにしません。
既存TEMP配下に練習ルートを用意
既存TEMPを起点に、ディレクトリ、空ファイル、値入りファイル、リンク、レジストリキーのちょうど五例を別名で試す。New-Itemの五つの基本例ではこの進め方により、操作したという事実ではなく、期待する状態へ到達したかでタイトルの問いへ答えられます。seq96の冪等な自動化パターンとは異なり、この記事は既存パス上でProvider差を学ぶ五例だけを提示する。
既存TEMP配下に練習ルートを用意の合格条件は、五つそれぞれのProvider、ItemType、FullNameまたはPSPathが期待どおりで、既存項目を変更していないことです。作業時刻、実行ユーザー、端末名を添え、判断に使った値が後から追える形にします。
例1:空のディレクトリ
例1:空のディレクトリは変更前の基準点です。既に存在する$env:TEMPを親にし、各例のLiteralPath、ItemType、既存有無を個別に確認するを出力に含め、取得時刻と一緒に保存します。値だけを切り取ると別対象との比較になるため、識別列を省きません。
$root = $env:TEMP
if (-not (Test-Path -LiteralPath $root -PathType Container)) { throw 'TEMPの親パスが存在しません。' }
$demo = Join-Path $root 'ittrip-new-item-five-examples'
$registryKey = 'HKCU:\Software\ITtripNewItemDemo'
@($demo, $registryKey) | ForEach-Object {
if (Test-Path -LiteralPath $_) { throw "既存項目と衝突します: $_" }
}
New-Itemの挙動はFileSystemやRegistryなどプロバイダーで異なる。親パスが存在することをTest-Pathで確認し、同名項目がある場合はForceで上書きせず例を止める。出力が多い場合も最初から無理に一件へ絞らず、候補数と除外理由を残してから対象を決めます。
例2:テキストファイル
例2:テキストファイルでは、既存TEMPを起点に、ディレクトリ、空ファイル、値入りファイル、リンク、レジストリキーのちょうど五例を別名で試す。New-Itemの五つの基本例の例中にある名前、パス、ID、時刻はサンプルなので、そのまま本番へ貼らず、直前の読み取り結果から承認値を入れます。
$isAdministrator = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(
[Security.Principal.WindowsBuiltInRole]::Administrator)
$developerMode = [int](Get-ItemPropertyValue -Path 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\AppModelUnlock' -Name AllowDevelopmentWithoutDevLicense -ErrorAction SilentlyContinue)
if (-not $isAdministrator -and $developerMode -ne 1) {
throw 'SymbolicLinkには管理者権限またはDeveloper Modeが必要です。何も作成していません。'
}
function Remove-IttripNewItemDemo {
if ($createdRegistryByThisRun -and (Test-Path -LiteralPath $registryKey)) {
Remove-Item -LiteralPath $registryKey -ErrorAction Stop
}
if ($createdDemoByThisRun -and (Test-Path -LiteralPath $demo)) {
foreach ($leafName in @('note-link.txt','note.txt','empty.txt')) {
$leafPath = Join-Path $demo $leafName
if (Test-Path -LiteralPath $leafPath) {
$leafItem = Get-Item -LiteralPath $leafPath -Force -ErrorAction Stop
if ($leafItem.PSIsContainer) { throw "cleanup refused for non-leaf: $leafPath" }
Remove-Item -LiteralPath $leafPath -ErrorAction Stop
}
}
if ([System.IO.Directory]::EnumerateFileSystemEntries($demo).GetEnumerator().MoveNext()) { throw 'demo root contains an unexpected item' }
Remove-Item -LiteralPath $demo -ErrorAction Stop
}
if (($createdRegistryByThisRun -and (Test-Path -LiteralPath $registryKey)) -or
($createdDemoByThisRun -and (Test-Path -LiteralPath $demo))) {
throw 'demo cleanup後も対象が残っています。'
}
}
$createdDemoByThisRun = $false
$createdRegistryByThisRun = $false
try {
$createdDir = New-Item -ItemType Directory -Path $demo -ErrorAction Stop
$createdDemoByThisRun = $true
$emptyFile = New-Item -ItemType File -Path (Join-Path $demo 'empty.txt') -ErrorAction Stop
$valueFile = New-Item -ItemType File -Path (Join-Path $demo 'note.txt') -Value 'New-Item sample' -ErrorAction Stop
$link = New-Item -ItemType SymbolicLink -Path (Join-Path $demo 'note-link.txt') -Target $valueFile.FullName -ErrorAction Stop
$key = New-Item -Path 'HKCU:\Software' -Name 'ITtripNewItemDemo' -ErrorAction Stop
$createdRegistryByThisRun = $true
$created = @($createdDir, $emptyFile, $valueFile, $link, $key)
if (@($created | Where-Object { $null -eq $_ }).Count -ne 0 -or $created.Count -ne 5) {
throw '5件すべての非null結果を取得できません。'
}
$dirCheck = Get-Item -LiteralPath $demo -ErrorAction Stop
$emptyCheck = Get-Item -LiteralPath $emptyFile.FullName -ErrorAction Stop
$valueCheck = Get-Item -LiteralPath $valueFile.FullName -ErrorAction Stop
$linkCheck = Get-Item -LiteralPath $link.FullName -Force -ErrorAction Stop
$keyCheck = Get-Item -LiteralPath $registryKey -ErrorAction Stop
$linkTarget = [IO.Path]::GetFullPath([string]@($linkCheck.Target)[0])
if (-not $dirCheck.PSIsContainer -or $emptyCheck.Length -ne 0 -or
(Get-Content -LiteralPath $valueCheck.FullName -Raw -ErrorAction Stop) -ne 'New-Item sample' -or
[string]$linkCheck.LinkType -ne 'SymbolicLink' -or
-not [StringComparer]::OrdinalIgnoreCase.Equals($linkTarget, [IO.Path]::GetFullPath($valueCheck.FullName)) -or
$keyCheck.PSProvider.Name -ne 'Registry') {
throw '種類、内容、link target、またはRegistry providerの個別検証に失敗しました。'
}
} catch {
$primary = $_.Exception.Message
try { Remove-IttripNewItemDemo } catch { throw "New-Item失敗=$primary; cleanup失敗=$($_.Exception.Message)" }
throw "New-Item失敗。限定cleanup確認済み: $primary"
}
-Forceで既存内容を置換しない。シンボリックリンク権限とレジストリのユーザー範囲を確認する。New-Itemの五つの基本例でプレビュー対応コマンドを使える場合はWhatIfを先に実行し、非対応の操作は対象一覧と引数を画面へ出して人が承認してから一度だけ実行します。
例3:ファイルへ初期値を入れる
例3:ファイルへ初期値を入れるでは同じ対象を別経路でもう一度読みます。判定したいのは「コマンドが終了したか」ではなく、五つそれぞれのProvider、ItemType、FullNameまたはPSPathが期待どおりで、既存項目を変更していないかどうかです。
$created | Select-Object @{n='NonNull';e={$null -ne $_}}, PSProvider, PSPath, Name, LinkType, Target
[pscustomobject]@{
ResultCount=$created.Count; NonNullCount=@($created | Where-Object { $null -ne $_ }).Count
Directory=$dirCheck.FullName; EmptyLength=$emptyCheck.Length
ValueContent=(Get-Content -LiteralPath $valueCheck.FullName -Raw)
LinkType=$linkCheck.LinkType; LinkTarget=$linkTarget; RegistryProvider=$keyCheck.PSProvider.Name
}
$cleanupToken = "CLEANUP-NEWITEM $demo AND $registryKey"
if ((Read-Host "5例を削除する場合だけ $cleanupToken を入力。残す場合はEnter") -eq $cleanupToken) {
Remove-IttripNewItemDemo
[pscustomobject]@{ DemoExists=(Test-Path -LiteralPath $demo); RegistryKeyExists=(Test-Path -LiteralPath $registryKey); CleanupVerified=$true }
}
親パスやリンク先がなければその例だけを保留し、存在しないC:Ops等を前提にしない。New-Itemの五つの基本例の期待値と実測値が一致しないときは追加変更を重ねず、対象識別、権限、ポリシー、時間差の順で原因を分けます。
例4:既存ファイルへのシンボリックリンク
-Forceで既存内容を置換しない。シンボリックリンク権限とレジストリのユーザー範囲を確認する。例4:既存ファイルへのシンボリックリンクに該当したら、警告を消して継続するのではなく、どの条件で止まったかを記録します。
親パスやリンク先がなければその例だけを保留し、存在しないC:Ops等を前提にしない。New-Itemの五つの基本例ではエラー本文、FullyQualifiedErrorId、対象ID、直前に成功した段階を残すと、別担当者が安全な地点から調査できます。
例5:既存キー配下のレジストリキー
練習用に作成した固有名だけを一覧で確認し、利用中でないことを承認してから個別に片付ける。復旧操作にも同じ識別条件を使い、名前が似た別対象へ戻し処理を適用しません。
- New-Itemの五つの基本例の変更前値と取得時刻
- 復旧対象: 既に存在する$env:TEMPを親にし、各例のLiteralPath、ItemType、既存有無を個別に確認する
- 復旧後の判定: 五つそれぞれのProvider、ItemType、FullNameまたはPSPathが期待どおりで、既存項目を変更していない
- 再実行を止める条件: -Forceで既存内容を置換しない。シンボリックリンク権限とレジストリのユーザー範囲を確認する
衝突時に上書きしない
各例を別コードブロックとして学び、同じ実行で五種類を無条件に量産しない。New-Itemの五つの基本例を繰り返す場合は、正常、対象なし、要承認、失敗を異なる終了状態として記録し、前回値との比較だけで異常を決めません。
| 衝突時に上書きしないの識別軸 | 既に存在する$env:TEMPを親にし、各例のLiteralPath、ItemType、既存有無を個別に確認する |
| 採用する実測 | 五つそれぞれのProvider、ItemType、FullNameまたはPSPathが期待どおりで、既存項目を変更していない |
| 0件時の扱い | 親パスやリンク先がなければその例だけを保留し、存在しないC:Ops等を前提にしない |
| 保留にする兆候 | -Forceで既存内容を置換しない。シンボリックリンク権限とレジストリのユーザー範囲を確認する |
質問:五例を後片付けするには
Q. New-Itemの五つの基本例は管理者PowerShellなら必ず成功しますか。A. いいえ。New-Itemの挙動はFileSystemやRegistryなどプロバイダーで異なる。親パスが存在することをTest-Pathで確認し、同名項目がある場合はForceで上書きせず例を止める。管理者権限は対象や製品仕様の不一致を解消しません。
Q. 0件を正常終了にできますか。A. 親パスやリンク先がなければその例だけを保留し、存在しないC:Ops等を前提にしない。要件上0件が許される場合だけ正常とし、検出できなかった状態とは分けて報告します。
New-Itemの五つの基本例の実行記録には、開始前の対象候補、採用した識別値、実行したコード、終了後の実測、除外した候補と理由を同じ作業番号で残します。特に「既に存在する$env:TEMPを親にし、各例のLiteralPath、ItemType、既存有無を個別に確認する」を省くと、後日の再確認で別対象の値を比較するおそれがあります。画面コピーだけでなく、日時と端末名を含む構造化した出力も保存します。
PowerShellのNew-Itemコマンド: 5つの具体的な利用例で理解するを定期手順へ組み込む場合も、初回は対話的に候補を確認します。正常時は「五つそれぞれのProvider、ItemType、FullNameまたはPSPathが期待どおりで、既存項目を変更していない」、判定不能時は「親パスやリンク先がなければその例だけを保留し、存在しないC:Ops等を前提にしない」、中止時は「-Forceで既存内容を置換しない。シンボリックリンク権限とレジストリのユーザー範囲を確認する」をそれぞれ別の結果として扱います。これにより、0件や例外を都合よく成功へ丸めず、次の担当者が同じ対象と条件で追試できます。
修正後コードの合格条件:5番目はNew-Itemが作成できるRegistryプロバイダーのキーです。レジストリ値はNew-ItemPropertyの責務なのでこの5例には数えず、作成したキーのPSProvider・PSPath・Nameを他4例と一緒に確認します。
再修正後は5件という配列長ではなく、各戻り値が非nullで、種類、完全パス、本文、シンボリックリンク先、Registry providerが期待どおりかを個別に確認します。途中失敗と明示cleanupはいずれも専用demo範囲だけを削除します。
公式情報・参考資料
New-Itemの五つの基本例で使うコマンド名、引数、対応環境は次のMicrosoft一次資料で確認しました。記事の確認日は2026年7月17日です。OSやモジュール更新後は、実行端末のGet-Helpと併せて再確認してください。

コメント