ファイルを置き換えるスクリプトを作成しました。ファイルの名前と検索するベースの場所のparamsを渡します。ワーカーラインは次のとおりです。
$SubLocations = Get-ChildItem -Path $Startlocation -Recurse -include $Filename -Force |
Where { $_.FullName.ToUpper().contains($Filter.ToUpper())}
$ Startlocationを "C:\ Users"に設定しましたが、他のユーザーのフォルダーを再帰しようとするとアクセスが拒否されます。私はそのマシンの完全な管理者であり、Powershellを管理者として実行してみました。 Windowsエクスプローラからすべてのファイルに問題なくアクセスできます。何か案が?
Get-ChildItem : Access to the path 'C:\Users\jepa227\Documents\My Music' is denied.
At C:\Users\krla226\Google Drive\Documents\PowerShell\Replace-File.ps1:35 char:46
+ $SubLocations = Get-ChildItem <<<< -Path $Startlocation -Recurse - include $Filename -Force |
+ CategoryInfo : PermissionDenied: (C:\Users\jepa227\Documents\My Music:String) [Get-ChildItem], Una
uthorizedAccessException
+ FullyQualifiedErrorId : DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand
[〜#〜]更新[〜#〜]
GCI経由で機能させることはできませんでしたが、WMIを使用して問題を解決することができました。興味のある人のために:
$SubLocations = Get-WmiObject -Class cim_datafile -Filter "fileName = '$filename' AND Extension = '$extension'" |
Where { $_.Name.ToUpper().contains($Filter.ToUpper()) }
これをWindows 7マシンで再現するには、「admin」という管理ユーザーとしてログインし、管理者特権でpowershellを実行し、UACを無効にします。
get-childitem "c:\users\Admin\my documents"
そして
cd "c:\users\admin\my documents"
get-childitem
記事 here に基づいて、My Documents、My Musicなどは、Vista以前のソフトウェアとの後方互換性のための接合点として定義されています。 Powershellは、ネイティブのジャンクションポイントではうまく機能しません。ここにはいくつかのオプションがあるようです:
1)Get-ChildItemコマンドから-forceを削除します。これはおそらくあなたの最善の策です。
get-childitem c:\users -recurse
エラーなしで動作し、ジャンクションポイントとAppDataのようなシステムディレクトリをスキップします。
編集者注:-Force
を省略すると、差し迫った問題は解決されますが、アクセスを引き起こす非表示のジャンクションポイントだけでなく、すべての非表示アイテムが常にスキップされます-deniedエラー。
2)何らかの理由で絶対に-Force
を使用する必要がある場合は、ジャンクションポイントをスキップして、プログラムで各サブディレクトリを再帰的に実行できます。 この記事 は、ジャンクションポイントを識別するメカニズムについて説明しています。 .ps1スクリプトファイルでのこのスケルトンは次のようになります。
Param( [Parameter(Mandatory=$true)][string]$startLocation )
$errorActionPreference = "Stop"
function ProcessDirectory( $dir )
{
Write-Host ("Working on " + $dir.FullName)
# Work on the files in this folder here
$filesToProcess = ( gci | where { ($_.PsIsContainer -eq 0) } ) # and file matches the requested pattern
# process files
$subdirs = gci $dir.FullName -force | where {($_.Attributes -band [IO.FileAttributes]::ReparsePoint) -eq 0 -and ($_.PsIsContainer -eq 1) -and (![string]::IsNullOrEmpty($_.FullName))}
foreach( $subdir in $subdirs )
{
# Write-Host( $subdir.Name + ", " + $subdir.FullName )
if ( $subdir -ne $null )
{
ProcessDirectory -dir $subdir
}
}
}
$dirs = get-childitem $startLocation -force
$dirs | foreach { ProcessDirectory -dir $_ }
mcatingの役立つ答え は問題をよく説明しています。
彼が提案する迅速な修正は、-Force
を省略することです。これは、PowerShell ignores-Force
が使用され、これらのシステム定義のジャンクションポイントにHidden
属性(ReparsePoint
およびSystem
属性とともに)。
一般的に非表示のアイテムを処理するために-Force
が必要であり、これらのシステム定義のジャンクションポイントのみを無視する場合は、 Get-ChildItem
の-Attributes
パラメータは次のとおりです。
Get-ChildItem -Force -Recurse -Attributes !Hidden, !System, !ReparsePoint
-Attributes
値excludes次の属性セットのallを持つすべてのアイテム:Hidden
、System
、ReparsePoint
、これはすべてのシステム定義の接合点に当てはまります。
これらの属性を使用して独自のジャンクションポイント(またはシンボリックリンク)を作成することは技術的には可能ですが、これは実際には起こりそうにありません。