L'un de mes scripts est utilisé pour extraire des données du site de ma société où sont enregistrés les tickets d'incidents, afin de créer des reportings pour mon client sur le mois passé.

Comme il se lance en tâche planifiée tous les 1 du mois, il va chercher tout seul comme un grand les dates actuelles et en déduit la date de début et date de fin. Récemment, nous avons eu à faire des requêtes pour extraire non pas sur le mois mais sur l'année entière. Et changer à chaque fois les dates en allant dans le script n'est pas des plus pratiques. Il a fallu changer tout ça!

Comment faire?

J'ai donc recherché une manière de faire autre, afin de pouvoir différencier le lancement d'un script par tâche planifiée ou le lancement d'un script en double-cliquant sur un fichier .ps1

La solution première qui m'est apparue était de me dire qu'un appui sur une touche dans un délai imparti permettrait de savoir qu'une personne est aux commandes, et qu'on pourrait donc renseigner les dates!

Etant donné que Read-Host bloque la console, se servir de cette commande aurait également bloqué l'exécution d'un script en tâche planifiée... on oublie!

Il y'a également la fonction readkey() disponible dans la variable $host qui permet de savoir quelle touche à été utilisée!

$host.ui.RawUI.ReadKey("noecho,includekeydown")

Mais hélas, elle aussi bloque la console en attente d'une touche...

Il existe une autre propriété dans $host.ui.RawUi, nommé "KeyAvailable", qui nous renvoie un booléen en fonction de si oui ou non une touche est appuyée... et qui n'est pas bloquante!

Il nous suffit donc de marier cette propriété et la fonction ReadKey() afin de pouvoir avoir un déclencheur de sortie de boucle sur appui de touche, puis une vérification de la touche utilisée!

On mixe le tout... et voila le script en question!

Ce test vous permettra d'avoir un décompte de 10 secondes, qui sera coupé soit par la fin du timer, soit par la fin par appui sur la touche L .

Attention : Powershell ISE ne bénéficie pas des fonctions de $host et ce script ne peut donc pas être utilisé dans ISE, uniquement en console PS classique.

$compte = 0

#On fait une première boucle, qui continue tant que ces conditions sont réunies : La touche appuyée n'est pas "l" et la variable compte est inférieure ou égale à 10
while ($key.character -ne "l" -and $($compte -le 10))
{
    #Deuxième boucle, qui va continuer tant qu'aucune touche n'est appuyée, et tant que compte est inférieure ou égale à 10
    While(-not $Host.UI.RawUI.KeyAvailable -and ($compte -le 10))
    {
          Write-Host -NoNewline "*"
          $compte++
          Start-Sleep -Seconds 1
    }

    #Des que l'on sort de la boucle, on vérifie si $compte est supérieure ou égale à 10 (fin du timer)
    if ($compte -ge 10)
    {
        Write-Host "Fin du décompte"
        break
    }
    #Sinon, on regarde quelle touche a été appuyée, ce qui mettra à jour la valeur $key et qui fera continuer / arrêter la première boucle
    else
    {
        #Utiliser "IncludeKeyUp" et pas "IncludeKeyDown" permet de détecter le moment ou l'appui sur la touche a été arrêté, car la boucle KeyAvailable sort des que la touche est appuyée, ce qui empêche IncludeKeyDown de détecter l'appui initial
        $key = $host.ui.rawui.readkey("NoEcho,IncludeKeyup")
    }
}
if ($key.character -eq "l")
{
    Write-Host "Vous avez appuyé sur une touche, bravo à vous. C'était $($key.character)"
}
Read-Host "Fin du script! :)"

Et le résultat? Le voici en image.

script1

script2

A vous de jouer!

Ajouter un commentaire

Article précédent Article suivant