Stopping * been entered as user input - powershell

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"
}

Related

Powershell Script to compare File-Hash from a Stream and published

Good morning guys,
I'm new to powershell scripting. And i can't figure out what I'm doing wrong.
I tried to write a .ps1 script to compare the hash value of a stream. I used the microsoft documentation for help and modify it to a runable script so i don't need to write it over and over again.
$wc = [System.Net.WebClient]::new()
$pkgurl = Read-Host "Please enter Package Url: "
$publishedHash = Read-Host "Enter Published Hash: "
$FileHash = Get-FileHash -InputStream ($wc.OpenRead($pkgurl))
if ($FileHash.Hash -eq $publishedHash) {
Write-Host "File Hash is equal to published Hash."
}
else {
Write-Host "File Hash NOT equal to published Hash."
}
When i run the script and enter the package url and the published Hash, the program all of a sudden abruptly shuts down.
Please, anyone an idea?
The script ends as it has nothing else to do.
You can add read-host at the end to wait for user input before it closes. (it wont do anything with the input, this just forces it to stay open until input has been made.)
Alternatively if you want to use it multiple times without it closing you can create a loop:
$KeepOpen = $true
While($KeepOpen -eq $true){
$wc = [System.Net.WebClient]::new()
$pkgurl = Read-Host "Please enter Package Url: "
$publishedHash = Read-Host "Enter Published Hash: "
$FileHash = Get-FileHash -InputStream ($wc.OpenRead($pkgurl))
if ($FileHash.Hash -eq $publishedHash) {
Write-Host "File Hash is equal to published Hash."
}
else {
Write-Host "File Hash NOT equal to published Hash."
}
$user_input = Read-Host "Please enter Y to run again"
if($user_input -ne "Y"){
$KeepOpen = $false
}
}
This will keep the script open so you can see the results and if you want it to run again insert Y and hit enter and you should be back to where you start.

Change currently running script

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.

Automatically Adding a Number to variable in Powershell

I have looked at some sites online and browsed a few answers here and I have had no luck with my question.
I have a PowerShell script to automate account creations using information entered in the host. My question is this, how can I set my script to automatically add a number at the end of the submitted data if it already exists? Code block is below:
$Username = Read-host "Enter Desired Username"
#Test
IF(!(Get-ADUser -Identity $Username))
{ Write-Host "$username exists. Adding number.
HERE IS THE CODE I AM LOOKING FOR TO TAKE THE $Username and automatically add the number at the end.
}
If this was already answered, please send me the link and I'll mark this as answered but if not, any suggestions would be great.
Thanks!
Since this script isn't being automatically run and there is user input, I would suggest just re-prompting the user if the name is taken:
Do
{
$Username = Read-Host -Prompt 'Enter desired username'
} While (Get-ADUser -Identity $Username)
Alternatively:
$Username = Read-Host -Prompt 'Enter desired username'
While (Get-ADUser -Identity $Username)
{
"Username '$Username' taken!"
$Username = Read-Host -Prompt 'Enter desired username'
}
To supplement the other answer, you could also do something like this to determine the next available username:
$Username = Read-Host -Prompt 'Enter desired username'
$TestUsername = $Username
$i = 1
While (Get-ADUser -Identity $TestUsername)
{
Write-Warning "$TestUsername is taken"
$TestUsername = $Username + $i++
}
"The next available username is $TestUsername"
Within the loop the ++ operator is used to increment the counter variable $i and appends that to the original username each time the loop repeats. Note that it is appended first then incremented second, so we start at 1.
I've written such a script. My logic is:
Before creating an account, query this account firstly
If the account exists, suffix a 2 digits number (from 01, format by "{0:d2}" -f
Query the suffixed account, repeat step 1 and 2, till the account doesn't exist (use recursive function).
It's the code:
$seq = 1
Function Check-Existing {
param(
[Parameter(Mandatory=$true)]
[string]$Account
)
while (Get-ADUser $Account){
$suffix = "{0:d2}" -f $seq
$Account = $Account + $suffix
$seq++
return $Account
}
Check-Existing -Account $Account
}
(I'll double check the code on Monday)

Powershell: message-box crashes do while loop

I have this simple script that just gets path an verifies if it exists.
function getPaths(){
$pathFromCMS = Read-Host "Please set the path for the copy files"
$pathToCMS = Read-Host "Please set the path to your CMS application"
if ((Test-Path -Path $pathFromCMS ) -and (Test-Path -Path $pathToCMS )){
Return $True
}
else{
[System.Windows.MessageBox]::Show('You have provided wrong path!')
Return $False
}
}
do{}while (! (getPaths) -eq $True)
echo "Hello there"
The problem is with the MessageBox::Show function. It somehow makes the loop stop when entering wrong paths. When I change it just for Write-Host "You have provided wrong path!" everything works fine. Can someone explain why this happens pls ?
The [System.Windows.MessageBox]::Show method returns a value, and that breaks your loop condition. You can suppress the return value by piping to Out-Null:
[System.Windows.MessageBox]::Show('You have provided wrong path!') | Out-Null
A MessageBox can have different buttons on it (e.g. YES/NO) and so is shown synchronously to allow you to capture what the user clicks. For example:
$preference = [System.Windows.MessageBox]::Show('Do you like MessageBoxes?', "MessageBox Preference", [System.Windows.MessageBoxButton]::YesNo)
In your case, even if you only want 'OK', it is still a good idea for it to wait, since the user always needs to manually dismiss it, unlike the output from Write-Host.
It is because there is nothing in your do{} block to be executed while the condition is satisfied.
What you want is:
do{(getPaths)}while ((getPaths) -ne $True)

Testing for Working Directory

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