How do I tell my script to go back to a certain point of the script? - powershell

Here is my script so far:
$BookTitle = Read-Host "Enter Book Title"
If ($BookTitle -eq "")
{
[System.Media.SystemSounds]::Beep.Play();
Write-Host "Please enter a book title"
}
Else
{
Write-Host "" ;
Write-Host "Book title is: $BookTitle"
}
What I want to do is if a user enters a book title that is null, I want the script to execute the error code block:
{
[System.Media.SystemSounds]::Beep.Play();
Write-Host "Please enter a book title"
}
and jump back to the beginning of this particular segment:
$BookTitle = Read-Host "Enter Book Title"
Instead of continuing on with the rest of the script. I don't want it to jump to the beginning of the entire script because I plan on using this kind of logic frequently within the script.
I'm not sure how to do it. I've tried using loops instead like Do...While, Do...Until, While, but I keep getting infinite loops.
So my question is, what am I doing wrong? Should I be using loops instead of conditional statements? A mixture of both?

Do {
$BookTitle = read-host "enter booktitle.."
[System.Media.SystemSounds]::Beep.Play();
} while ($BookTitle -eq "")
$BookTitle

Related

Powershell Switch Break Label not being executed

As part of a larger script I have implemented the switch detailed below. The intention is that when the script is executed a user can choose to either
enter users to be migrated on-screen, or
import from a file.
If the import from file option is selected - I want to test the file is present - if not I want to break out and go back to the switch label :choose. However when I select the import from file option and provide a non-existent path the script continues and does not break or return to the label. Where am I going wrong?
$chooseInputMethod = #"
This script migrates one or more user accounts between two trusted domains in a forest e.g. from domain1 to domain2 (or vice versa)
Select method to specify user(s) to migrate:
1. Enter name(s) on-screen (default)
2. Import name(s) from file
Enter selection number
"#
$choosePath = #"
Enter path to file..
Notes
- Filename:
If file is located in script directory ($pwd) you can enter the filename without a path e.g. users.txt
- No quotation marks:
DO NOT put any quotes around the path even if it contains spaces e.g. e:\temp\new folder\users.txt
Enter path or filename
"#
$enterUsernames = #"
Enter username(s) seperate each with a comma e.g. test1 or test1,test2,test3`n`nEnter name(s)
"#
cls
:choose switch (Read-Host $chooseInputMethod) {
1 { cls; $usersFromScreen = Read-Host $enterUsernames }
2 {
cls;
$usersFromFile = Read-Host $choosePath;
if (-not (Test-Path $usersFromFile -PathType Leaf)) {
break choose
}
}
default { cls; $usersFromScreen = Read-Host $enterUsernames }
}
Write-Host "hello"
From the documentation for break:
In PowerShell, only loop keywords, such as Foreach, For, and While can have a label.
So, switch, even though it has looping capabilities, is not considered a loop in this case.
However, in this case I don't see why break without a label would not suffice.
A break to the switch will exit it. There's only one loop (switch, which works on arrays), so there's no difference between a plain break and breaking to the switch. You seem to want the switch inside another loop to repeat it.
# only runs once
:outer while (1) {
'outer'
while (1) {
'inner'
break outer
}
}
outer
inner
Demo of switch with a label and looping. The documentation isn't perfect.
# only runs once
:outer switch (1..10) {
default {
'outer'
foreach ($i in 1..10) {
'inner'
break outer
}
}
}
outer
inner
Another switch demo.
switch (1..4) {
{ $_ % 2 } { "$_ is odd" }
default { "$_ is even" }
}
1 is odd
2 is even
3 is odd
4 is even

Return output from Powershell script to UIPath using Invoke power shell

I am trying to get a value from an input box from a Powershell script back to a UI Path Sequence. I have created a simple sequence as an example. Yes, I know I could do this all in UI Path, I am just using an easy example as a way to try and test this for future use cases. Here is my sequence:
My text file from "Read text file" is:
$test = "Desktop/PassingArgs2of2.ps1 -Message foo"
Invoke-Expression -Command $test
The activity in UiPath looks like so:
The psCmd that I am running in the Invoke power shell activity looks like this:
Param(
[parameter(Mandatory=$true)]
[string]
$Message)
try{
$Global:fooVar = $null
function Test-InputBox(){
[void][Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic')
$msg = "fooMsg"
$title = "fooTitle"
$localtest = [Microsoft.VisualBasic.Interaction]::InputBox($msg, $title)
$Global:fooVar = $localtest.ToString()
}
Test-InputBox
}
catch{}
I tried setting fooVar equal to testLocal in the PowerShellVariables within Invoke power shell and then writing it, but that did not work.
Basically I want to get fooVar back into UI Path. Any help would be greatly appreciated. Thank you!
You're almost there. First, your Powershell script has to return a value. Take this for example:
[void][Reflection.Assembly]::LoadWithPartialName('Microsoft.VisualBasic')
$title = 'Your title goes here'
$msg = 'Your favorite color:'
$text = [Microsoft.VisualBasic.Interaction]::InputBox($msg, $title)
return $text
Here's the script in action (note that I called it twice and provided "red" the first time:
Then, just use this script directly in the Invoke Powershell activity. Note that the most important part here is the Output property - here, I decided to go for an array of strings. Naturally, as we only return a single value, you can just access the text provided by the user by accessing output(0).ToString().

EWS Delete PhoneNumber Entry on Contact

I try to Delete an phone number Entry within an contact while using the ExchangeWebService and powershell.
I can create new Contacts with Numbers and so on. I can even change those numbers. But i can set then to $null or "".
It always gives me Exception calling "Update" with "1" argument(s): "An object within a change description must contain one and only one property to modify."
I understand that im not allowed to set it to "" or null. But there have to be a way to delete a phone number entry.
So may be there is someone out there to help me with this issue.
So far i check if there is a change in the phone number and only update it where there is.
$enumBusinessPhoneValue = [Microsoft.Exchange.WebServices.Data.PhoneNumberKey]::BusinessPhone
if($c.PhoneNumbers[$enumBusinessPhoneValue] -ne "" -and $c.PhoneNumbers[$enumBusinessPhoneValue] -ne $null){
if($busPhone -ne ""){
if($c.PhoneNumbers[$enumBusinessPhoneValue] -ne $busPhone){
echo "="
$c.PhoneNumbers[$enumBusinessPhoneValue] = $busPhone
}
} else {
$c.PhoneNumbers[$enumBusinessPhoneValue] = ""
}
} else {
if($busPhone -ne ""){
$c.PhoneNumbers[$enumBusinessPhoneValue] = $busPhone
}
}
$c.Update([Microsoft.Exchange.WebServices.Data.ConflictResolutionMode]::AlwaysOverwrite)
The problem lies in this line $c.PhoneNumbers[$enumBusinessPhoneValue] = "" even if i put in $null i get the same error.
Greetings
skratter
You need to use the Extended Property for the Business Phone in this case (this is the same as for EmailAdddresses https://blogs.msdn.microsoft.com/emeamsgdev/2012/05/17/ews-managed-api-how-to-remove-email1-email2-email3-from-a-contact/) eg
$PidTagBusinessTelephoneNumber = new-object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(0x3A08,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::String);
$c.RemoveExtendedProperty($PidTagBusinessTelephoneNumber)
$c.Update([Microsoft.Exchange.WebServices.Data.ConflictResolutionMode]::AlwaysOverwrite)

Appending variable to string to pull value of existing variable

I'm currently learning PowerShell and I can't work out how to combine a string and a variable to pull information from an existing variable.
The user input will just be a number, so 1,2,3 etc. which I need to append to the end of $option which will pull the title information from the variable $optionX.
So far everything I've tried just interprets it as a string and print $OptionX into the console, as opposed to the value held by $OptionX.
So for example:
function Title{
Write-host "$OptionName for:"$computerSystem.Name -BackgroundColor DarkCyan
}
function GetMenu {
# Set the menu options
$Option1 = "1) System Information"
# Get menu selection
$Navigation = Read-Host "Enter Selection"
ToolBox
}
function ToolBox{
Clear-Host
switch ($Navigation){
1 { #Script 1
Title
}
You can do what you do in the self-answer. I would suggest using a hash-map for it though - seems cleaner to me. (I have no idea what the $computersystem.Name-part is, so I just left it in):
function Title{
Write-host "$($Options[$Navigation]) for:"$computerSystem.Name -BackgroundColor DarkCyan
}
function GetMenu {
# Set the menu options
$Options = #{
"1" = "1) System Information"
"2" = "2) Something else"
}
# Get menu selection
$Navigation = Read-Host "Enter Selection"
ToolBox
}
function ToolBox{
Clear-Host
switch ($Navigation){
1 { #Script 1
Title
}
}
}
For the rest of your script I can see that you are using Global Variables extensively, which I would avoid (it will confuse you, makes it harder to understand what is going on, and many other reasons not to use them). Look into using parameters for your functions, using the snippet menu (CTRL+J) in Powershell ISE will make a quick function skeleton for you. When you want to develop further in Powershell functions look into the Cmdlet (advanced function) template in the same menu.
I figured out how to do it, I'm not sure if it's the best method but it does what I need it to do.
function Title{
$OptionCombine = "Option"+$Navigation
$OptionName = Get-variable $OptionCombine -ValueOnly
Write-host "$OptionName for:"$computerSystem.Name -BackgroundColor DarkCyan
}

How do I force input to be string only?

I need the user to input a title of a book.
I need to make sure they input string only.
This is where I'm at so far, any guidance please.
Do { $strTitle = Read-host "Enter the book title"}
while ($strTitle -eq "")
What do you mean by string? alpha characters only?
You could try a regular expressions.
Regular Expression to match only alphabetic characters
http://powershell.com/cs/blogs/tobias/archive/2011/10/27/regular-expressions-are-your-friend-part-1.aspx
Code to check for alpha characters:
Do {
$strTitle = Read-host "Enter the book title"
} until ($strTitle -notMatch "[^[:alpha:]]")