Principes de base de PowerShell
Dans cette série de blogs, mon objectif est de vous convaincre d'apprendre PowerShell. J'espère toucher un public plus large que celui des développeurs avec ce billet. Si vous êtes un consultant ERP non développeur, ce blog est aussi pour vous. En fait, PowerShell n'est pas un outil créé pour les développeurs, il a été conçu pour servir les administrateurs de systèmes et les consultants et leur permettre d'automatiser les tâches d'administration informatique. Mais les développeurs peuvent également tirer beaucoup de puissance de la connaissance et de l'utilisation de PowerShell dans leur développement quotidien.
Si vous prétendez ne pas connaître PowerShell, vous avez probablement tort. Si vous avez déjà utilisé des outils de ligne de commande ou exploré des systèmes par le biais d'une ligne de commande, vous connaissez un peu PowerShell, car il est superposé à la ligne de commande de base. Nous allons donc commencer ce blog par une navigation et une manipulation fondamentales du système de fichiers. Nous allons utiliser un cas d'utilisation réel pour automatiser la mise à jour d'une bibliothèque de référence afin de pointer vers une version différente d'Acumatica Files.
Cas d'utilisation : Mettre à jour le dossier de la bibliothèque de référence de Dell pour utiliser une version différente d'Acumatica
D'après mon expérience de travail avec de nombreux développeurs Acumatica différents, ils ont tous une façon différente de connecter les références Visual Studio à une instance d'Acumatica. J'ai récemment appris de mon collègue développeur MVP Stephan Belanger qu'il existait une façon très astucieuse d'effectuer cette tâche. La stratégie est simple. Les fichiers Dll sont copiés du répertoire Acumatica Bin dans un dossier du projet Visual Studio et les références sont à leur tour pointées vers ces fichiers. Ce que j'AIME dans cette stratégie, c'est que le projet VS peut maintenant être construit sans avoir besoin d'une instance réelle d'Acumatica vers laquelle pointer. Vous n'avez donc même pas besoin que le site Web soit chargé dans la solution. Cela se prête bien à tout processus de construction automatisé ou CI/CD. Tant que les dlls de la version cible d'Acumatica se trouvent dans le dossier Library, tout va bien. Plus besoin de chercher des références à chaque fois que vous avez l'intention de travailler sur une nouvelle version d'Acumatica. Tout ce que vous avez à faire est de mettre à jour les fichiers. Nous allons automatiser cette opération en utilisant des appels de ligne de commande fondamentaux et en les enchaînant dans un script PowerShell.
ISE vs PowerShell Prompt
Il existe deux façons fondamentales d'utiliser PowerShell. La première est l'ISE (Integrated Scripting Environment). La seconde est l'invite PowerShell. En général, vous utiliserez l'environnement de script intégré ISE pour développer, dépanner et maintenir les scripts PowerShell. Vous utiliserez ensuite l'invite PowerShell pour utiliser et consommer les scripts et services PowerShell. Une autre différence est que l'ISE a Intel sense et que l'invite PowerShell a quelque chose de similaire appelé Tab. Chacun fait la même chose, mais de manière très différente.
Achèvement de l'onglet
Pour explorer l'achèvement des onglets, ouvrons l'invite PowerShell et identifions le dossier des fichiers que nous voulons mettre à jour. Ouvrez le menu Démarrer et tapez PowerShell. Vous obtiendrez quelque chose comme l'image ci-dessus. L'invite PowerShell est l'option sans le suffixe ISE. Ouvrons-la. Il y a de fortes chances que vous connaissiez la commande DOS DIR, qui permet d'obtenir une liste de répertoires. Nous pouvons rechercher notre cible en tapant DIR puis c:\ ou le lecteur qui contient le projet. Saisissons la première lettre du répertoire suivant, puis appuyons sur la touche de tabulation. Vous verrez apparaître le premier répertoire commençant par cette lettre. Si vous n'avez pas atteint le répertoire souhaité, appuyez à nouveau sur la touche de tabulation et répétez l'opération jusqu'à ce que vous atteigniez le répertoire suivant. Si vous êtes allé trop loin et que vous souhaitez revenir au répertoire précédent, utilisez la touche shift tab. Commencez à taper la lettre ou les deux lettres suivantes, puis appuyez sur la touche de tabulation jusqu'à ce que vous atteigniez la partie suivante du chemin. C'est ainsi que fonctionne la complétion de tabulation fondamentale. Il s'agit essentiellement d'une intelligence pour un système de ligne de commande non graphique. Tout ce dont vous devez vous souvenir, ce sont ces deux choses. Il y a beaucoup de choses au-delà de la navigation dans les systèmes de fichiers qui utilisent également la complétion de tabulation.
Tab = passer au suivant.
Majuscule Tab = déplacer le précédent.
IntelliSense dans ISE
Nous allons maintenant voir comment cela fonctionne dans l'environnement de script intégré. Dans le menu Démarrer, ouvrons l'autre option PowerShell, à savoir l'ISE. En plus de la complétion des tabulations, vous verrez qu'une fenêtre IntelliSense s'ouvre pour vous aider à naviguer dans le système de fichiers. Identifions maintenant le dossier de fichiers.
Tout ce qui précède est une interface de ligne de commande standard sur laquelle PowerShell est construit. Nous pouvons maintenant ajouter une fonctionnalité que vous ne trouverez pas dans la ligne de commande seule. En effet, nous pouvons charger les résultats dans une variable PowerShell. Il suffit d'utiliser le caractère $ pour préfixer le nom d'une variable, puis d'utiliser le caractère = suivi de la commande que nous venons d'exécuter. Au lieu de retaper toute la commande, il suffit d'appuyer sur la flèche vers le haut pour afficher la dernière commande. Maintenant, si vous appuyez sur votre touche home, votre curseur se retrouvera au début de la ligne. Tapez $libFiles = puis entrez. Il semble que rien ne se soit passé, mais si vous tapez maintenant $libFiles, vous verrez qu'il renverra les résultats qui ont été précédemment renvoyés par la commande DIR seule.
Ce que nous pouvons faire avec cette variable, c'est la faire passer par une commande foreach et faire quelque chose avec chacun des fichiers. Copions la ligne qui contient l'affectation de la variable dans l'éditeur de script de l'éditeur ISE. Après cette ligne, nous ajouterons le fichier foreach et nous renverrons simplement le nom du fichier à l'hôte. Vous remarquerez peut-être que vous n'obtenez pas d'IntelliSense lorsque vous tapez $libFile.name. C'est parce que la variable n'a jamais été initialisée. Une astuce lors de l'exécution de ces boucles foreach est d'exécuter la boucle une seule fois et de renvoyer le fichier lui-même. Maintenant, si vous exécutez le script (utilisez F5 comme raccourci), vous pourrez interagir avec le dernier objet de la boucle. Il s'agit d'une fonctionnalité très puissante de PowerShell, qui permet d'interagir avec des objets pendant la construction d'un script. Celui-ci se présentera comme suit.
Maintenant, ce que nous devons faire dans cette boucle, c'est trouver les dll mises à jour qui doivent remplacer la liste chargée dans notre variable $libFiles. Ce que nous devons savoir maintenant, c'est où se trouve le dossier bin des fichiers sources dont nous avons besoin. Tout ce que nous avons besoin de savoir à ce stade est le répertoire Acumatica et nous pouvons déduire le dossier bin à partir de celui-ci. À ce stade, nous allons demander à l'utilisateur du script d'entrer cette information. Pour ce faire, nous ferons appel à la commande Read-Host.
Lire l'hôte
La commande Read-Host est très utile. J'aime particulièrement l'utiliser lorsque je travaille sur un script inachevé et j'enlève généralement la commande Read-Host du script à des étapes ultérieures du script. Essentiellement, tout ce que fait Read-Host est de demander à l'utilisateur final une valeur de chaîne de caractères. Les chaînes vides ou le simple fait d'appuyer sur la touche Entrée sont des entrées acceptables. Cela introduit également un mécanisme permettant d'ajouter un délai dans un script afin d'attendre l'achèvement d'une tâche manuelle. J'aime utiliser cette technique dans les premières étapes de l'automatisation d'un processus lorsque je peux obtenir d'un utilisateur humain qu'il effectue temporairement une tâche manuelle tout en étant capable d'automatiser une partie du processus. Je démarre souvent un script avec seulement des lignes Read-Host. Une pour chaque étape du processus que l'on souhaite automatiser. Quelque chose comme ce qui suit.
Il ne se passe rien dans le script ci-dessus, si ce n'est qu'il invite l'utilisateur à effectuer une tâche manuelle. Pour l'instant, nous cherchons à automatiser l'étape 6. Une fois celle-ci mise en place, nous pourrons remplacer cette ligne par notre script de travail et nous aurons alors un script semi-automatisé qui comporte un certain processus manuel, mais qui permet néanmoins de gagner du temps par rapport au nombre incalculable de fois où ce processus doit être répété. Je constate souvent que je n'ai pas beaucoup de temps pour terminer un script. Mais si j'ai l'habitude de rendre le script ci-dessus légèrement plus automatisé à chaque exécution avec le peu de temps dont je dispose. En réalité, à long terme, cette automatisation me permettra de gagner encore plus de temps pour affiner et réduire le travail manuel à chaque itération.
Pour en revenir à notre objectif d'automatiser la mise à jour des dll, nous allons ajouter ces lignes au début du script.
Nous avons un bloc do while où la commande Test-Path va valider si la valeur saisie est bonne. Nous pouvons voir que la ligne Read-Host invitera l'utilisateur et chargera la valeur dans une variable. La ligne suivante formate la valeur d'entrée en une chaîne de caractères qui doit pointer vers le répertoire bin. L'invite se répète jusqu'à ce qu'une valeur valide soit saisie. Il s'agit d'un moyen très simple d'obtenir des informations de la part d'un utilisateur. Il existe des moyens plus élégants de le faire. Étant donné que nous disposons de toute la puissance de .NET au sein de PowerShell, nous pouvons même faire apparaître des boîtes de dialogue modales qui aideront à la sélection. Dans ce blog, nous n'abordons que les bases. Mais nous aborderons un sujet plus avancé qui inclut l'octroi d'une entrée GUI dans un prochain blog de cette série. Nous avons ce dont nous avons besoin, nous allons donc passer à la partie suivante.
Maintenant que nous savons où se trouvent les dll sources, nous pouvons mettre à jour notre boucle pour qu'elle fasse le travail que nous recherchons. Etant donné que l'invite PowerShell est difficile à utiliser, nous pouvons l'utiliser pour explorer la partie suivante. Au fur et à mesure que nous trouvons des éléments qui fonctionnent, nous pouvons utiliser la touche flèche vers le haut pour obtenir la dernière commande et l'ajouter à la partie script. Si vous utilisez la complétion par tabulation ou l'intelligence sur la variable $labile, vous pouvez déterminer que nous allons avoir besoin des valeurs fullname et name. Chargeons-les dans des variables comme ceci.
Nous pouvons alors concaténer le dossier source et la destination en tant que tels et nous connaissons maintenant le chemin de destination et le chemin source du fichier qui doit être copié.
Sans revenir à la ligne de commande de base, nous pouvons utiliser la commande copy pour faire le travail.
Voici ce qu'il en est :
Mais nous pouvons ajouter quelques noms de paramètres PowerShell pour rendre cette opération un peu plus compréhensible.
Une fois que nous avons testé que cela fonctionne pour la commande unique, nous pouvons maintenant utiliser le dépôt de toutes les lignes de travail dans le script. Au lieu d'utiliser la touche flèche vers le haut pour chacune d'entre elles, nous pouvons utiliser Get-History ou simplement hist pour obtenir toutes les commandes que nous avons saisies dans cette session. Get-History est un autre outil utile lors de la construction de scripts, car il permet d'éviter de retaper des éléments que vous avez explorés à l'aide de l'invite PowerShell. Il suffit de faire un copier-coller pour insérer ces lignes dans la boucle foreach. Notre résultat final est le suivant.
Exécutons le script et voyons si nous obtenons les résultats souhaités. Si tous les fichiers sont dans la version souhaitée, c'est que l'opération a réussi.
Fonctions
Nous pouvons affiner ce script en encapsulant ce qui est nécessaire dans une fonction. Et au lieu d'avoir un répertoire LibFiles statique et une invite Read-Host, nous pouvons les configurer en tant que paramètres car ce sont les deux éléments d'information nécessaires à cette tâche. Dans la section param(), nous définirons deux variables et leur type sera System.IO.FileInfo. L'avantage de définir ce type de variable au lieu de la chaîne par défaut est que lorsque vous utilisez cette fonction à l'invite de PowerShell, elle saura que vous recherchez un chemin. En retour, vous bénéficiez de tous les avantages de l'IntelliSense ou de la complétion de tabulation qui facilitent les choses.
Une ligne comme celle-ci automatisera ce qui était auparavant un processus manuel. Si ce processus est répété des centaines de fois par an, le retour sur investissement du temps passé à créer ce script sera rapidement amorti.
Résumé de ce que nous avons appris
L'objectif de ce blog est d'utiliser un outil de ligne de commande "copy" commun pour automatiser le processus de copie manuelle de ces fichiers. Nous avons appris que tout ce que vous pouvez faire en ligne de commande, vous pouvez le faire avec des scripts PowerShell. Il est intéressant de savoir comment effectuer une tâche à partir de la ligne de commande, car vous pouvez gagner beaucoup de temps en incorporant ce que vous savez sur la ligne de commande dans un script PowerShell. Nous en avons appris un peu plus sur les deux outils différents permettant d'utiliser PowerShell, à savoir l'invite PowerShell et l'ISE (Integrated Scripting Environment) PowerShell. Read-Host est un outil puissant pour introduire des délais contrôlés, demander des informations aux utilisateurs ou les inviter à effectuer une étape manuelle qui sera ensuite entièrement automatisée. La complétion des tabulations et l'IntelliSense permettent d'économiser des frappes et d'explorer des objets de manière interactive. Nous avons appris à utiliser Test-Path pour affirmer qu'un chemin existe et nous l'avons incorporé dans une boucle do whilepour valider une entrée Read-Host. Nous n'avons pas abordé la création de fonctions en détail, mais nous avons terminé le blog en convertissant notre script en fonction. Nous avons créé des paramètres de type System.IO.FileInfo, ce qui nous permet d'utiliser la complétion de tabulation et IntelliSense lors de la saisie des chemins source et destination nécessaires.
Suivant
Nous allons automatiser davantage le processus d'initialisation d'une bibliothèque d'extension Acumatica dans une fonction. Le prochain élément que nous voulons automatiser est de rediriger la solution pour envoyer la bibliothèque d'extension vers le répertoire Bin de l'instance Acumatica cible. Nous allons aborder les principes fondamentaux de PowerShell et la façon dont il peut être utilisé pour charger des données à partir de fichiers CSV ou XML. Notre objectif sera de mettre à jour les fichiers XML du projet et de la solution afin de rediriger les données vers le processus de construction.
Bonne lecture !