我写了一个替换文件的脚本。我将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()) }
答案 0 :(得分:4)
我能够在Windows 7计算机上重现这一点,并使用以下命令登录为管理员用户名为&#34; admin&#34;,使用提升的权限运行powershell,并禁用UAC:
get-childitem "c:\users\Admin\my documents"
和
cd "c:\users\admin\my documents"
get-childitem
根据文章here,看起来像我的文档,我的音乐等,被定义为与Vista之前的软件向后兼容的连接点。 Powershell本身并不适用于交接点。看起来这里有几个选项:
1)从Get-ChildItem命令中删除-force。这可能是你最好的选择。
get-childitem c:\users -recurse
无错误地工作,并跳过连接点和系统目录,如AppData。
编者注:省略-Force
确实解决了当前的问题,但总是跳过所有隐藏的项目,而不仅仅是导致访问的隐藏交接点 - 否认错误。
2)如果出于某种原因绝对需要使用-Force
,则可以通过编程方式递归每个子目录,跳过连接点。 This article描述了识别交接点的机制。 .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 $_ }
答案 1 :(得分:1)
mcating's helpful answer很好地说明了问题。
他建议的快速解决方案是省略-Force
,这是可行的,因为除非使用-Force
,否则Powershell 忽略隐藏项,并且这些系统定义的连接点确实具有Hidden
属性(以及ReparsePoint
和System
属性)。
如果您确实需要-Force
来处理隐藏项目,而只想忽略这些系统定义的接合点,则可以使用Get-ChildItem
的{ {1}}参数如下:
-Attributes
Get-ChildItem -Force -Recurse -Attributes !Hidden, !System, !ReparsePoint
值排除设置了 all 以下属性的所有项目:-Attributes
,Hidden
,{{ 1}},对于所有系统定义的接合点都是如此。
尽管从技术上讲可以使用这些属性创建自己的接合点(或符号链接),但这在实践中不太可能发生。