我能够在 Windows 7 计算机上重现此问题,使用以下命令以名为“admin”的管理员用户身份登录,以提升的权限运行 powershell,并禁用 UAC:
get-childitem "c:\users\Admin\my documents"
and
cd "c:\users\admin\my documents"
get-childitem
根据文章here http://answers.microsoft.com/en-us/windows/forum/windows_vista-security/access-denied-to-the-my-documents-and-settings/915eecc8-6a07-4d6a-8ca5-468ee51e9484?auth=1,看起来“我的文档”、“我的音乐”等被定义为与 Vista 之前的软件向后兼容的连接点。 Powershell 本身并不擅长处理连接点。这里似乎有几个选择:
1) 从 Get-ChildItem 命令中删除 -force。这可能是您最好的选择。
get-childitem c:\users -recurse
工作时不会出现错误,并且会跳过连接点和系统目录(例如 AppData)。
Editor's note: Omitting -Force
does solve the immediate problem, but invariably skips all hidden items, not just the hidden junction points that cause the access-denied errors.
2)如果您绝对需要使用-Force
由于某种原因,您可以以编程方式递归每个子目录,跳过连接点。本文 https://stackoverflow.com/questions/2311105/test-in-powershell-code-if-a-folder-is-a-junction-point描述了识别连接点的机制。 .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 $_ }