My first steps were to create 2 variables and set their value to args[0] and args[1], then have an if statement containing some error checking with Write-Warning and a Read-Host to capture user input and store the value in the variables.
Here is my code:
# Create 2 command line variables
$workingdirectory = ARGS[0]
$directoryname = ARGS[1]
## Check if variables are empty and get user input if necessary
if ("$workingdirecytory" -eq "") {
Write-Warning "Parameter Required"
$workingdirectory = Read-Host "Enter absolute path to working directory"
Write-Warning "Parameter Required"
$directoryname = Read-Host "Enter directory name to search for in $workingdirectory"
}
Write-Host "$workingdirectory"
Write-Host "$directoryname"
The question is:
Write an if statement like this: If (“$WorkingDirectory” –eq “”) {
Inside the script blocks add the following:
use Write-Warning cmdlet to display a message “Parameter Required”
use Read-host to capture user input and store the value in the variable $WorkingDirectory
Repeat for DirectoryName
Am I suppose to have another if statement for the directory name?
Trying to make the output look like this:
by:
Now execute your code by typing the file name with no parameters
Execute the code by typing the file name and one parameter
Execute the code with the correct parameters
Related
I have a PowerShell script (which I cannot change) with the following function inside it:
function Foo ([string] param1) {
[...]
$var1 = Read-Host "Test"
$var2 = Read-Host "Test2"
[...]
}
I want to call the function from my PowerShell script and want to prevent that the user has to input any values, instead I want to prepare hardcoded values.
I tried the following:
#("Var1Value", "Var2Value") | Foo "Param1Value"
But it still prompts the user. Any ideas?
During command discovery, functions take precedence over binary cmdlets, so you can "hide" Read-Host behind a fake Read-Host function:
# define local Read-Host function
function Read-Host {
param([string]$Prompt)
return #{Test = 'Var1Value'; Test2 = 'Var2Value'}[$Prompt]
}
# call foo
foo
# remove fake `Read-Host` function again
Remove-Item function:\Read-Host -Force
I have a script to create a user account in my domain.
I have added a Middle name which is optional, but is required if the username is going to be a duplicate, so will take the middle name initial to differentiate.
The problem is that the following code keeps the last value. So if I specify first, middle and last name, then the next user is first and last name, then it still keeps the middle name.
Is there something that keeps the middle name empty when it runs the next time from scratch?
Do
{
#Getting variable for the First Name
Do
{
$firstname = Read-Host "Enter in the First Name"
Write-Host
if ($firstname -ge 1) {
Write-Host "First name is $firstname"
}
else
{
Write-Host "Please enter the first name" -ForegroundColor:Green
}
}
Until ($firstname -ge 1)
$option = Read-Host "Does the person have a middle name? (y/n)"
if ($option -eq "y")
{
#Getting variable for the Middle Name
Do
{
$middlename = Read-Host "Please enter the middle name"
Write-Host
if ($middlename -ge 1)
{
Write-Host "Middle name is $middlename"
}
else
{
Write-Host "Please enter the middle name" -ForegroundColor:Green
}
}
Until ($middlename -ge 1)
}
else
{
Write-Host "No middle name required"
}
#Getting variable for the Last Name
Do
{
$lastname = Read-Host "Enter in the Last Name"
Write-Host
if ($lastname -ge 1)
{
Write-Host "Last name is $lastname"
}
else
{
Write-Host "Please enter the last name" -ForegroundColor:Green
}
}
Until ($lastname -ge 1)
#Setting Full Name (Display Name) to the users first and last name
if ($middlename)
{
$fullname = "$firstname $middlename $lastname"
Write-Host $fullname
sleep 5
}
else
{
$fullname = "$firstname $lastname"
}
#Write-Host
#Setting username to first initial of first name along with the last name.
$i = 1
$logonname = $firstname.substring(0,$i) + $lastname
Just clear the variable at the beginning of your script.
Either:
$middlename = ""
Or use Remove-Variable
Remove-Variable middlename
This behavior comes from how you choose to launch a script. You have essentially two options in PowerShell, Invocation (Running) or dot-sourcing (Loading).
Take this short script.
#stack.ps1
"my variable should be empty $myVar"
$myvar = "cat"
"my variable should have a value $myVar"
When I run it / invoke it in PowerShell using the Invocation operator, look what happens:
PS> & .\stack.ps1
my variable should be empty
my variable should have a value cat
PS> & .\stack.ps1
my variable should be empty
my variable should have a value cat
PowerShell runs the script and so the script stores its variable values in the script scope. Meaning that when the script ends, the variables disappear.
Versus Dot-Sourcing
Now, compare that to dot-sourcing, which runs a script in your present context.
PS> . .\stack.ps1
my variable should be empty
my variable should have a value cat
PS> . .\stack.ps1
my variable should be empty cat #!!!! the value persisted!
my variable should have a value cat
Because it runs in your present context, the values persist when the script ends.
If I had to guess, I'd say you might be dot-sourcing your script instead of invoking it. It is a very easy thing to do and would explain what you're seeing.
Is there any way to add text to specific part of script to the currently running script?
If i have a menu with options:
Install All
Add item
Quit
Could the Add item be possible?
Learning to use powershell (heavy user of batches).
When entering Add item, then a read-host would pop up, adding a row between the long row of ### addwifi -wnm $USERINPUT afterwards 'restarting' the script.
Current script:
#cmd: title Add****
$host.ui.RawUI.WindowTitle = "Add Wi-Fi networks"
#When Show-Menu –Title 'SetupWi-Fi' is called
function Show-Menu
{
# NOTE if changing warible from somewhere else (Show-Menu -WARIBLE VALUE) then param part must be included
param (
[string]$Title = 'SetupWi-Fi'
)
Clear-Host
#cls and echo on #echo off
Write-Host "================ $Title ================"
Write-Host "a: Add Wi-Fi networks."
Write-Host "q: Quit."
}
#Do this until x
#For future shortening purposes
function addwifi
{
param (
[string]$wnm
#wnm= wifi name
)
netsh wlan add profile filename="$wnm.xml"
#for some reason (nice for this script) . stops the warible name
}
do
{
# call Show-Menu and optionally change varible: –Title 'Warible' changes the $title varible
Show-Menu
# makin varible chaase equal user input, placing Selection before it
$chaase = Read-Host "Selection:"
#switch according to the varible chaase
switch ($chaase)
{
'a' {
#'single quote' acts as echo, now executing commands of 'a' varible
'Adding Wi-Fi networks.'
$host.ui.RawUI.WindowTitle = "Adding Wi-Fi networks"
#note the upper function is called with warible
#add below here! #####################################################################
addwifi -wnm laptopidee
#add above here! #####################################################################
}
#close a execution
#close switch
}
#close do
}
#until x: selection == input q
until ($chaase -eq 'q')
One possibility is to use placeholders that you replace at runtime, though I'm not sure how well it will hold up for more complex scripts.
For example, if you have the following script:
$scriptPath = "$PsScriptRoot\$($MyInvocation.MyCommand.Name)"
$scriptContent = Get-Content "$PsScriptRoot\$($MyInvocation.MyCommand.Name)" -Raw
$newItem = Read-Host "Please enter new command"
##Placeholder
$scriptContent -replace "$([char]0x0023)$([char]0x0023)Placeholder", "$([char]0x0023)$([char]0x0023)Placeholder$([char]0x000D)$([char]0x000A)$newItem" |
Set-Content -Path $scriptPath
Each time you run it, you will be prompted for a new command, which will be added below the ##Placeholder. So, if you enter Get-Process when prompted, the script would end up on-disk like this:
$scriptPath = "$PsScriptRoot\$($MyInvocation.MyCommand.Name)"
$scriptContent = Get-Content "$PsScriptRoot\$($MyInvocation.MyCommand.Name)" -Raw
$newItem = Read-Host "Please enter new command"
##Placeholder
Get-Process
$scriptContent -replace "$([char]0x0023)$([char]0x0023)Placeholder", "$([char]0x0023)$([char]0x0023)Placeholder$([char]0x000D)$([char]0x000A)$newItem" |
Set-Content -Path $scriptPath
Next time you run the script you will be prompted for a new command, which is added to the list, and all commands already on the list will be executed.
Yes. Use external files as sources to be pulled in. The Add Item menu option creates another file to be read in at next execution.
Many people did this with batch files using .ini files to hold parameters. Similar construct.
I have a script which asks for user input and then uses it as a variable to validate a directory path exists, however when a user inputs * the validation comes back successful where it should fail.
the input is done via Read-Host, sample of the code is below.
$userinput = Read-Host -Prompt "Enter Value"
if(Test-Path -Path "c:\$userinput\") {"Valid"} else {"not valid"}
Just writing #PetSerAl's comment as an answer
-path treats * as a wild card which likely causes the success.
The solution is to use -LiteralPath which treats the path literally.
$userinput = Read-Host -Prompt "Enter Value"
if(Test-Path -LiteralPath "c:\$userinput\")
{
"Valid"
}
else
{
"not valid"
}
In my profile script for powershell I want to write to user input, so that when i start powershell I will already have something in my input and have only to press enter.
I need something like "write-input".
I have already tries "echo", "write-input".
I would do something like:
$defaultvalue = "This is the default value"
$a = read-host -Prompt "$defaultvalue (enter)"
if (!$a) {$a = $defaultvalue}
write-host "the value is now $a"