J'ai un script PowerShell qui utilise du.exe ( tilisation du disque originaire de Sysinternals) pour calculer la taille des répertoires.
Si je lance du c:\Backup
dans la console, cela fonctionne comme prévu, mais la même ligne de code exécutée dans ISE ou PowerGui donne le résultat attendu plus l'erreur
+ du <<<< c:\backup
+ CategoryInfo : NotSpecified: (:String) [], RemoteException
+ FullyQualifiedErrorId : NativeCommandError
Pourquoi donc? Comment éviter cette erreur? J'ai essayé invoke-expression, en utilisant &
, mais non.
Merci pour l'aide.
Pour éviter cela, vous pouvez rediriger stderr vers null, par exemple:
du 2> $null
Essentiellement, la console Host et ISE (ainsi que l'accès à distance) traitent le flux stderr différemment. Sur l'hôte de la console, il était important pour PowerShell de prendre en charge des applications comme edit.com pour fonctionner avec d'autres applications qui écrivent des sorties colorées et des erreurs à l'écran. Si le flux d'E/S n'est pas redirigé sur l'hôte de la console, PowerShell donne à l'EXE natif un descripteur de console sur lequel écrire directement. Cela contourne PowerShell afin que PowerShell ne puisse pas voir qu'il y a des erreurs écrites, il ne peut donc pas signaler l'erreur via $ error ou en écrivant dans le flux stderr de PowerShell.
ISE et l'accès à distance n'ont pas besoin de prendre en charge ce scénario afin qu'ils voient les erreurs sur stderr et écrivent ensuite l'erreur et mettent à jour $ error.
J'ai récemment été confronté aux mêmes problèmes, mais je voudrais que la sortie stderr soit dirigée vers stdout. On pourrait penser que ce qui suit fonctionnerait:
& du 2>&1
Mais PowerShell interprétera la redirection et la traitera une fois 'du' terminé. La solution que j'ai trouvée consiste à l'invoquer à l'aide de cmd.exe/c:
& cmd /c 'du 2>&1'
Une autre façon de supprimer la sortie NativeCommandError
est de convertir les objets du pipeline en chaînes comme indiqué au bas de cette réponse :
du c:\Backup 2>&1 | %{ "$_" }
Le FIX précédent redirigera les erreurs mais vous pourriez perdre une véritable erreur si, par exemple, votre nom d'utilisateur ou votre mot de passe n'est pas bon ou si vous utilisez l'authentification intégrée, vous n'y avez pas accès.
Voici donc un moyen d'implémenter la gestion des erreurs et de contourner l'erreur spécifique (qui n'en est pas une) déclenchée par psexec.
try{
psexec command .....
}
catch [System.Management.Automation.RemoteException]{
if ($_.TargetObject -like "Connecting to *" -and $_.CategoryInfo.Category -eq "NotSpecified" -and $_.FullyQualifiedErrorId -eq "NativeCommandError" -and $_.InvocationInfo.MyCommand.Name -like "psexec*.exe"){
$error.Remove[$Error[0]]
}
else{
Throw
}
}
catch{
throw
}
Essayer:
du 2>&1 | %{ "$_" }