J'ai un script que j'ai écrit qui remplace les fichiers. Je lui passe les paramètres pour le nom du fichier et l'emplacement de la base de recherche. Les lignes de travail sont:
$SubLocations = Get-ChildItem -Path $Startlocation -Recurse -include $Filename -Force |
Where { $_.FullName.ToUpper().contains($Filter.ToUpper())}
J'ai défini $ Startlocation sur "C:\Users", cependant, l'accès est refusé lorsque j'essaie de recurse à travers les dossiers d'autres utilisateurs. Je suis administrateur complet sur la machine et j'ai déjà essayé d'exécuter Powershell en tant qu'administrateur. Je peux accéder à tous les fichiers via l'Explorateur Windows sans problème. Une idée?
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
METTRE &AGRAVE; JOUR
Alors que je ne pouvais pas le faire fonctionner via GCI, j'ai pu utiliser WMI pour résoudre mon problème. Pour ceux intéressés:
$SubLocations = Get-WmiObject -Class cim_datafile -Filter "fileName = '$filename' AND Extension = '$extension'" |
Where { $_.Name.ToUpper().contains($Filter.ToUpper()) }
J'ai été en mesure de reproduire cela sur un ordinateur Windows 7 à l'aide de la commande suivante, connectée en tant qu'utilisateur admin nommé "admin", exécutant powershell avec des privilèges élevés et le contrôle de compte d'utilisateur désactivé:
get-childitem "c:\users\Admin\my documents"
et
cd "c:\users\admin\my documents"
get-childitem
D'après l'article ici , on dirait que Mes documents, Ma musique, etc., sont définis comme des points de jonction pour une compatibilité ascendante avec les logiciels antérieurs à Vista. Powershell ne fait pas bien nativement avec les points de jonction. Il semble y avoir quelques options ici:
1) Supprimez -force de la commande Get-ChildItem. C'est probablement votre meilleur pari.
get-childitem c:\users -recurse
fonctionne sans erreur et ignore les points de jonction et les répertoires système comme AppData.
Note de l'éditeur: Omettre -Force
résout le problème immédiat, mais ignore invariablement tous les éléments cachés , et pas uniquement les points de jonction masqués à l'origine des erreurs d'accès refusé.
2) Si vous devez absolument utiliser le -Force
pour une raison quelconque, vous pouvez ré-initialiser par programme chaque sous-répertoire en ignorant les points de jonction. Cet article décrit le mécanisme d'identification des points de jonction. Un squelette de ceci dans un fichier script .ps1 pourrait ressembler à ceci:
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 $_ }
La réponse utile de mcating explique bien le problème.
La solution rapide qu'il suggère est d'omettre -Force
, ce qui fonctionne, car PowerShell ignore éléments masqués, sauf si -Force
est utilisé, et ces points de jonction définis par le système ont l'attribut Hidden
(à côté des attributs ReparsePoint
et System
).
Si vous avez besoin de -Force
pour traiter les éléments masqués en général et que vous souhaitez uniquement ignorer ces points de jonction définis par le système , vous pouvez utiliser le paramètre Get-ChildItem
de -Attributes
comme suit:
Get-ChildItem -Force -Recurse -Attributes !Hidden, !System, !ReparsePoint
La valeur -Attributes
exclut tous les éléments pour lesquels tous des attributs suivants sont définis: Hidden
, System
, ReparsePoint
, ce qui est vrai de tous les points de jonction définis par le système.
Bien qu'il soit techniquement possible de créer vos propres points de jonction (ou liens symboliques) avec ces attributs, il est peu probable que cela se produise dans la pratique.