web-dev-qa-db-fra.com

Erreur lors de l'appel d'un exécutable tiers à partir de Powershell lors de l'utilisation d'un IDE

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.

62
Lucas

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.

46
Keith Hill

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'
37
Simon Ejsing

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 | %{ "$_" }
20
sschuberth

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
            }
2
Patrick Larose

Essayer:

du 2>&1 | %{ "$_" }
2
Ivan