1
votes

Powershell Get-Content échoue faussement

J'ai un script PS assez simple qui fonctionnait parfaitement et qui a soudainement commencé à donner des erreurs. J'ai réduit la partie du problème à quelques déclarations Get-Content. Voici à quoi ressemble la partie affectée du script:

Get-Content : A parameter cannot be found that matches parameter name 'Encoding'.
At D:\FileDirectory\Script.ps1

Cette partie du script rassemble une collection de fichiers portant le même nom et les concatène en un seul fichier texte pour téléchargement sur un site FTP . Le fichier Get-Content / Out-File était nécessaire car les fichiers d'origine ne sont pas encodés correctement pour le site FTP. Le script fonctionnait parfaitement, fonctionnant une fois par nuit pendant plusieurs semaines. Maintenant, il obtient l'erreur suivante lorsque les instructions Get-Content sont atteintes:

$pathSource = "D:\FileDirectory"
Set-Location -Path $pathSource
Get-Content -Encoding UTF8 -Path FilesA*.txt | Out-File -Encoding ASCII FilesA_Digest.txt
Get-Content -Encoding UTF8 -Path FilesB*.txt | Out-File -Encoding ASCII FilesB_Digest.txt

L'environnement est Windows Server 2016. J'ai essayé différentes variantes des paramètres Get-Content, mais rien n'a fonctionné. Je sais qu'un bogue affecte les lecteurs mappés en réseau, mais ce n'est pas le cas ici - tous les fichiers sont locaux.

Des idées / suggestions?


7 commentaires

-Path FilesA * .txt inclurait Out-File FilesA_Digest.txt lors des exécutions successives.


En aparté: l'application de -Encoding ASCII aux données (à l'origine) encodées en UTF-8 peut entraîner une perte d'informations : tous les caractères de l'entrée qui sont en dehors de la plage ASCII sera translittérée en caractères littéraux ? . (En revanche, si les données d'origine contiennent uniquement des caractères ASCII, il n'y a aucun besoin de transcoder, étant donné que UTF-8 est un sur-ensemble d'ASCII.)


@LotPings - c'était une faute de frappe de ma part, car j'utilisais des noms de fichiers factices qui ne correspondent pas au script d'origine. Le script original ne souffre pas de ce problème.


@ mklelement0 - Je me rends compte qu'il peut y avoir un problème de perte de données, mais la réalité est qu'il n'y en aura pas, car le fichier source ne contient aucun caractère en dehors de l'ensemble ASCII standard.


@npowroz: Je vois, mais cela contredit votre affirmation "les fichiers originaux sont mal encodés": Si vous pouvez les lire correctement avec -Encoding UTF8 et ils ne contiennent que de l'ASCII- plage de caractères, vous n'avez pas du tout besoin de transcodage.


@ mklelement0: Je sautais des détails qui n'avaient pas d'importance. La réalité est que les fichiers ont été créés par Powershell encodés comme "UCS-2 LE BOM". L'application de réception à la fin de la connexion FTP bombarde quand elle voit cela, donc en ajoutant les paramètres -Encoding, le problème de codage est résolu.


@npowroz: Si vos fichiers ont une nomenclature, ce que vous transmettez à -Encoding lorsque vous appelez Get-Content est sans importance et en passant UTF8 , qui ne correspond pas au codage réel , est déroutant. (Il semble que l'encodage réel soit UTF-16LE (que PowerShell appelle de manière trompeuse Unicode ), c'est ce que je suppose que vous entendiez par «UCS2 LE», ce qui, à proprement parler, n'est pas identique à UTF-16LE. UTF-16LE (avec BOM) est ce que Windows PowerShell produit par défaut avec > et Out-File (mais pas < / i> avec Set-Content )).


3 Réponses :


1
votes

La seule explication plausible à laquelle je puisse penser est que une commande personnalisée Get-Content sans paramètre -Encoding est observer (remplacer) l'applet de commande Get-Content standard dans la session PowerShell qui exécute votre script.

Pour démontrer:

PS> (Get-Command Get-Content -All)[-1].ModuleName
Microsoft.PowerShell.Management

Vous verrez le même message d'erreur que dans votre question.

Utilisez Get-Command Get-Content -All pour tout voir commandes nommées Get-Content , avec la commande effective répertoriée en premier.

Ensuite, examinez d'où peuvent provenir les commandes personnalisées; par exemple, votre script $ PROFILE peut en contenir un.

Pour exclure $ PROFILE comme coupable , démarrez PowerShell sans charger le script de profil et examiner Get-Content puis:

Microsoft.Powershell.Management\Get-Content ...

Un moyen simple d'exclure les remplacements personnalisés ad hoc consiste à appeler une commande par son nom qualifié de module :

powershell -noprofile  # Windows PowerShell
pwsh -noprofile        # PowerShell Core

Vous pouvez déterminez le nom du module d'origine d'une applet de commande intégrée comme suit:

# Define a custom Get-Content command (function) that accepts only 
# a (positional) -Path parameter, not also -Encoding.
function Get-Content { [CmdletBinding()] param([string] $Path) }

# Now try to use Get-Content -Encoding
Get-Content -Encoding Utf8 FilesA*.txt

En un clin d'œil, vous pouvez également déduire le nom du module d'origine à partir de l ' URL de la rubrique d'aide :


10 commentaires

J'ai essayé toutes vos suggestions et j'obtiens toujours la même erreur, alors maintenant je suis vraiment perdu. Je sais que j'utilise le Get-Content intégré sans remplacement, sans personnalisation, sans rien de spécial. C'est vraiment bizarre.


@npowroz: Donc, si vous exécutez votre script * .ps1 à partir d'une instance PowerShell que vous avez démarrée avec -noprofile et qui rapporte Microsoft.PowerShell.Management < / code> pour (Get-Command Get-Content) .ModuleName vous obtenez toujours la même erreur?


@npowroz: Si vous faites Format-Hex , cela ressemble-t-il à la présence de caractères de contrôle invisibles dans votre fichier?


Faire "Get-Command Get-Content" renvoie "Version 3.1.0.0 / Source Microsoft.PowerShell.Management" après l'avoir démarré avec -noprofile. Je l'ai vidé en utilisant Format-Hex, mais je ne vois rien qui me dépasse.


@npowroz: vérifiez si le problème est spécifique à une machine donnée avec une version PowerShell / OS donnée.


Je viens de le tester sur une instance de Windows Server 2008, exécutant n'importe quelle version de PowerShell qui l'accompagne (1.0 je pense). Même erreur - (pour paraphraser) "Le paramètre -Encoding is invalid". La seule chose qui me vient à l'esprit est qu'un patch a cassé des choses, mais je ne sais pas si je suis même dans le bon univers.


@npowroz: Quel est le message d'erreur exact ? Est-ce différent de celui que vous citez dans votre question?


Non, c'est exactement le même que celui que j'ai cité dans la question initiale. C'est la raison pour laquelle j'ai paraphrasé. Toutes mes excuses si cela a créé un hareng rouge. Et je sais que ce n'est pas un problème de profil sur cette machine car je n'ai jamais exécuté PowerShell dessus. De plus, l'appel à Get-Content était le formulaire long "Microsoft.Powershell.Management \ Get-Content -Encoding ..."


@ mklelement0: C'est devenu plus étrange. J'ai testé Get-Content sur un serveur différent, une autre implémentation de Server 2016. Cela a parfaitement fonctionné, sans erreur. Fait intéressant, cette machine est un peu démodée avec ses correctifs. Je penche de plus en plus vers un mauvais correctif qui brise l'applet Get-Content dans Powershell.


@npowroz: W2K8 en effet à l'origine est venu avec PSv1, que personne ne devrait plus utiliser - vous ne pouvez même plus trouver de documentation, donc je ne peux pas dire si Get-Content de la v1 avait un paramètre -Encoding . Même si ce n'était pas le cas, cela n'expliquerait pas comment votre script fonctionnant précédemment a cessé de fonctionner - à moins que vous ne l'exécutiez sur une machine différente . $ PSVersionTable.PSVersion vous indiquera la version exécutée par une machine donnée.



0
votes

Cela semble être un problème avec la commande out. Pouvez-vous essayer le code ci-dessous:

$pathSource = "D:\FileDirectory"
Set-Location -Path $pathSource
Get-Content -Encoding UTF8 -Path FilesA*.txt | Set-Content  -Encoding ASCII -path FilesA_Digest.txt
Get-Content -Encoding UTF8 -Path FilesB*.txt | Set-Content  -Encoding ASCII -path FilesB_Digest.txt


1 commentaires

Out-File n'est pas le problème, étant donné que le message d'erreur de l'OP mentionne clairement Get-Content comme cmdlet incriminée: Get- Contenu: impossible de trouver un paramètre correspondant au nom de paramètre "Encoding".



0
votes

Eh bien, je ne sais pas pourquoi cela a échoué, mais je peux dire que j'ai complètement réécrit le script et qu'il fonctionne maintenant. Je dois noter que, compte tenu des erreurs qui se produisaient, je ne sais pas non plus pourquoi cela fonctionne maintenant.

J'utilise exactement les mêmes appels à la commande Get-Content, avec le paramètre -Encoding et le tube vers Out-File avec son propre paramètre -Encoding. Je fais exactement les mêmes actions que la version précédente du script. La seule partie qui est significativement différente est la partie qui effectue le transfert FTP des fichiers traités. J'utilise maintenant uniquement PowerShell pour effectuer le transfert plutôt que CuteFTP et tout semble fonctionner correctement.

Merci à tous ceux qui ont contribué.

Acclamations Norme


0 commentaires