Puis-je utiliser des variables existantes dans PowerShell read-host

Nov 07 2020

J'écris un script simple dans PowerShell en utilisant "read-host -prompt" afin que je puisse saisir du texte qui sera ensuite utilisé pour créer des variables d'environnement.

Existe-t-il un moyen que les fois suivantes, le script est exécuté, le message read-host affichera une valeur existante pour la variable si elle existe? et si ce n'est pas ce que je veux alors accepter ma nouvelle entrée pour changer cette variable?

par exemple ...

$myvar = read-host -prompt "whats your value" and i enter 10 to set $valeur myvar à 10

la prochaine fois que le script est exécuté, "quelle est votre valeur" affichera 10, et si j'appuie sur entrée sans changer la valeur, il utilisera à nouveau la valeur 10 .. si j'entre une nouvelle valeur, il mettra à jour $ myvar à la nouvelle valeur

Merci pour toute aide

Réponses

1 CFou Nov 09 2020 at 13:54

Vous ne pouvez pas faire ceci directement:

####[int]$myVar = 10 Read too fast the question :) #$myVar = Get-ItemProperty ...
#or
#myVar = Get-Content ...
$tempVar = Read-Host "Enter the value ($myVar is default)"
if ($tempVar) { $myVar = $tempVar } $myVar
# Store $myVar in the registry or in the file for next run

Mon mauvais, j'ai répondu sans une bonne lecture :) Comme l'a dit @postanote, si vous avez besoin de garder une trace de la valeur de chaque exécution, vous pouvez la stocker dans un fichier (à mon humble avis, j'éviterais le profile.ps1) ou dans une clé de registre personnelle. Ensuite, lisez le fichier ou la valeur de registre pour initialiser votre variable.

1 mklement0 Nov 09 2020 at 14:35

Si je comprends bien, vous recherchez deux fonctionnalités qui ne sont pas implémentées dans Read-HostPowerShell 7.1:

  • (a) Préremplir le tampon d'édition avec une valeur par défaut , que l'utilisateur peut soit accepter telle quelle, soit modifier.

    • L'alternative est simplement d' informer l'utilisateur, via la -Promptchaîne, quelle valeur sera utilisée s'il n'en saisit pas une nouvelle, mais de cette façon vous ne pourrez pas faire la distinction entre l'utilisateur choisissant la valeur par défaut ou souhaitant simplement abandonner l'invite (ce qu'ils pourraient faire avec Ctrl-C, cependant).
  • (b) Conserver un historique permanent des valeurs entrées par l'utilisateur qui se souvient (au moins) de la valeur la plus récemment entrée, à travers les sessions PowerShell .

Remarque: Read-Hostest actuellement simple. Le module qui fournit la riche expérience d'édition de ligne de commande interactive pour PowerShell lui-même est PSReadLine, et serait génial si ses fonctionnalités, qui incluent un historique persistant et la modification du tampon d'édition, pouvaient être mises à la disposition du code utilisateur pour des invites générales - voir Proposition GitHub n ° 881 . Faire apparaître de
telles améliorations viaRead-Host est probablement la meilleure option, ou du moins la possibilité de pré-remplir le tampon d'édition pourrait y être implémentée: voir la proposition GitHub # 14013 .

Voir les implémentations personnalisées - limitées - de (a) et (b) ci-dessous.


(a) est actuellement uniquement possible via une solution de contournement , et uniquement sur Windows , à la fois dans les fenêtres de console normales et le terminal Windows (cela ne fonctionne pas (de manière assez fiable) dans le PowerShell ISE obsolescent Merci, CFou . , et dans le terminal intégré de Visual Studio Code cela ne fonctionne que si vous placez le focus dessus en cliquant immédiatement après le lancement d'une session de débogage):

# The (default) value to pre-fill the Read-Host buffer with.
$myVar = 'This is a default value.' # Workaround: Send the edit-buffer contents as *keystrokes* # !! This is not 100% reliable as characters may get dropped, so we send # !! multiple no-op keys first (ESC), which usually works. (New-Object -ComObject WScript.Shell).SendKeys( '{ESC}' * 10 + ($myVar -replace '[+%^(){}]', '{$&}') ) $myVar = Read-Host 'Enter a value'  # Should display prompt with value of $myVar

Remarque: L' -replaceopération est nécessaire pour échapper les caractères de la valeur par défaut qui auraient autrement une signification particulière .SendKeys().

(b) vous oblige à implémenter votre propre mécanisme de persistance, et le choix évident est d'utiliser un fichier :

Voici une approche simpliste qui ne stocke que la valeur la plus récente entrée.

  • La prise en charge de plusieurs valeurs historiques par invite prendrait également en charge le rappel dans Read-Host, comme l'utilisation de la flèche vers le haut et la flèche vers le bas pour parcourir l'historique, ce qui n'est pas pris en charge à partir de PowerShell 7.1.
# Choose a location for the history file.
$historyFile = "$HOME/.rhhistory" # Read the history file (which uses JSON), if it exists yet. $history = Get-Content -Raw -ErrorAction Ignore $historyFile | ConvertFrom-Json $defaultValue = 'This is a default value.'

# Get the 'myVar' entry, if it exists, otherwise create it and use the default value.
$myVar = if (-not $history) { # no file yet; create the object to serialize to JSON later
    $history = [pscustomobject] @{ myVar = '' } $defaultValue
  } elseif (-not $history.myVar) { # file exists, but has no 'myVar' entry; add it. $history | Add-Member -Force myVar ''
    $defaultValue } else { # return the most recently entered value. $history.myVar
  }

# Prompt the user.
(New-Object -ComObject WScript.Shell).SendKeys(
  '{ESC}' * 10 + ($myVar -replace '[+%^(){}]', '{$&}')
)
$myVar = Read-Host 'Enter a value' # Validate the value... # Update the history file with the value just entered. $history.myVar = $myVar $history | ConvertTo-Json > $historyFile