Automatically Adding a Number to variable in Powershell - 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)

Related

How to validate 2 inputs in Powershell and only proceed when both inputs are validated

Trying to write a script in Powershell that needs to validate 2 User Inputs before applying policies to the correct entries. With the basic script I wrote, It Validates the 1st Entry which is the User ID in the Teams Tenant. Then Validates the 2nd entry which is the telephone number using the validate regex. The problem I am having is that the policies Do not get applied when the correct information is applied. It skips that part and states a Warning and asks to check another profile.
Connect-MicrosoftTeams
do {
try {
# 1st User Entry to check UserID
$upnentry = Read-Host 'Enter the User Principle Name'
# Validate in Teams Tenant if this ID exists, If Not,
# prompt to enter a valid entry again
$csu = Get-CsOnlineUser -Identity $upnentry -ErrorAction Stop
$csu | Format-List IsSipEnabled, Displ*
Write-Host 'User ID has been verified correctly!'
# 2nd User Entry to check for valid Telephone Number
$phoneinputblock = {
try
{
[validatescript({[regex]::Match($_,'^27\d{9}$').Length -eq 11})]
$phoneUserInput = Read-Host "`nEnter Telephone Number"
$phoneUserInput
}
catch{ Write-Warning "Incorrect Format for Telephone Number!"
& $phoneinputBlock
}
}
$phoneuserInput = & $phoneinputBlock
Write-Host 'Telephone Number is in the correct format!'
Set-CsPhoneNumberAssignment -Identity $user -PhoneNumber
$phonenumberinput -PhoneNumberType DirectRouting
Grant-CsOnlineVoiceRoutingPolicy -PolicyName VRP- International -Identity $upnentry
Write-host "Policies applied successfully for : $upnentry" - ForegroundColor Green
}
catch { Write-Warning "You've entered an invalid UserID: $upnentry"
}
} until($Host.UI.PromptForChoice('', 'Do you want to check another Users Profile?',
('&Yes', '&No'), 0))
I would not perform the two tests inside nested try--catch blocks like that, but instead use a boolean variable to keep track of the result from the first test and only if that is true proceed with the rest.
Something like this:
Connect-MicrosoftTeams
do {
$testID = $false
try {
# 1st User Entry to check UserID
$upnentry = Read-Host 'Enter the User Principle Name'
# Validate in Teams Tenant if this ID exists, If Not,
# prompt to enter a valid entry again
$csu = Get-CsOnlineUser -Identity $upnentry -ErrorAction Stop
$csu | Format-List IsSipEnabled, Displ*
Write-Host 'User ID has been verified correctly!'
$testID = $true
}
catch { Write-Warning "You've entered an invalid UserID: $upnentry"}
if ($testID) {
# 2nd User Entry to check for valid Telephone Number
while ($true) {
$phoneUserInput = Read-Host "`r`nEnter Telephone Number"
if ([regex]::Match($phoneUserInput,'^27\d{9}$').Length -eq 11) {
Write-Host 'Telephone Number is in the correct format!'
break # exit the loop
}
# here we have a wrong phone number, so ask again
Write-Host "`r`nThe Telephone Number is in the wrong format. Should start with 27 followed by nine digits" -ForegroundColor Red
if ((Read-Host "Do you want to stop here (Yes/No) ?") -match '^Y') { # exit the script
exit
}
}
# here we know both entries are correct, so proceed setting the phone number
try {
Set-CsPhoneNumberAssignment -Identity $upnentry -PhoneNumber $phoneUserInput -PhoneNumberType DirectRouting -ErrorAction Stop
Grant-CsOnlineVoiceRoutingPolicy -PolicyName 'VRP- International' -Identity $upnentry -ErrorAction Stop
Write-host "Policies applied successfully for: $upnentry" - ForegroundColor Green
}
catch {
Write-Warning "Error setting the phone number: $($_.Exception.Message)"
}
}
} until ($Host.UI.PromptForChoice('', 'Do you want to check another Users Profile?', ('&Yes', '&No'), 0))

set-mailboxautoreplyconfiguration breaks scandinavian characters

I've created a powershell script that removes all licences and group memberships from a person when he/she is leaving the company and adds an automatic reply to their mailbox. Everything else is going fine, except when i added Scandinavian letters into the hardcoded auto-reply.
bold The error is only for hard coded data. Everything that is prompted is read correctly
if ( "y" -eq $Automaattivastaus) {
$Username = Read-Host -Prompt "Nimi automaattivastaukseen"
$Paivamaara = Read-Host -Prompt "Milloin henkilön työsuhde on päättynyt?"
$Vastaanottaja = Read-Host -Prompt "automaattivastaus, Mihin sähköpostiin ottaa yhteyttä"
set-MailboxAutoReplyConfiguration -identity $Email -AutoReplyState Enabled -InternalMessage "Henkilön $Username palvelussuhde on päättynyt $Paivamaara. Pyydän kääntymään hänen työtehtäviensä hoitoon liittyvissä asioissa sovelletaan Lakia yksityisyyden suojasta työelämässä (759/2004)."
"snippet from auto reply Pyydän kääntymään hänen työtehtäviensä hoitoon liittyvissä asioissa."
As you can see the characters break. If anyone would have the solution how to fix this I would be grateful.
Connect-ExchangeOnline -UserPrincipalName "my.account#test.com" -ShowProgress $true
Add-Type -AssemblyName system.web
$Username = "Täältä pesee! Härifrån tvättas!"
$Paivamaara = "15.06.2021"
$Vastaanottaja = "Öland"
$Email = "test.account#test.com"
$Automaattivastaus = "Henkilön $Username palvelussuhde on päättynyt $Paivamaara. Pyydän kääntymään hänen työtehtäviensä hoitoon liittyvissä asioissa
($Vastaanottaja) puoleen. Mikäli viestisi on luonteeltaan yksityisluontainen, pyydän ottamaan yhteyttä suoraan henkilöön $Username. Yksityisluontaiset viestit tuhotaan ilman niiden avaamista. Työhön liittyvien viestien selvittämiseen ja avaamiseen
sovelletaan Lakia yksityisyyden suojasta työelämässä (759/2004)."
$t = [web.httputility]::Htmldecode($Automaattivastaus)
set-MailboxAutoReplyConfiguration -identity $Email -AutoReplyState Enabled -InternalMessage ([web.httputility]::Htmldecode($t)) -ExternalMessage ([web.httputility]::Htmldecode($t))
I don't have Exchange available, so I can't check this. Anyway, since ExternalMessage wraps the message automatically within HTML tags, try and convert the string into HTML escaped form. That will escape åäö and other characters that need escaping in HTML. Like so,
# Load assembly that contains the utility class
add-type -AssemblyName system.web
# A demo string with Finnish and Swedish letters
$s = "Täältä pesee! Härifrån tvättas!"
# Encode the string.
$t = [web.httputility]::HtmlEncode($s)
$t
Täältä pesee! Härifrån tvättas!
# The encoding is reversable, obviously.
[web.httputility]::Htmldecode($t)
Täältä pesee! Härifrån tvättas!
Edit:
Call the ENcode version, it will convert ääkköset into escped forms. the DEcode will reverse the encoding. It is not needed here, and was included as for illustration purposes only. Like so,
$Automaattivastaus = "Henkilön $Username palvelussuhde on päättynyt $Paivamaara..."
$encodedAnswer = [web.httputility]::HtmlEncode($Automaattivastaus)
set-MailboxAutoReplyConfiguration -identity $Email -AutoReplyState Enabled -InternalMessage $encodedAnswer -ExternalMessage $encodedAnswer
What if you would enclose the message in quotation marks and set the encoding?
$Username = Read-Host -Prompt "Nimi automaattivastaukseen"
$Paivamaara = Read-Host -Prompt "Milloin henkilön työsuhde on päättynyt?"
$Vastaanottaja = Read-Host -Prompt "automaattivastaus, Mihin sähköpostiin ottaa yhteyttä"
$message = "<html><head><meta charset='UTF-8'></head>
<body>
Henkilön $Username palvelussuhde on päättynyt $Paivamaara. Pyydän kääntymään hänen työtehtäviensä hoitoon liittyvissä asioissa sovelletaan Lakia yksityisyyden suojasta työelämässä (759/2004).
</body>
</html>"
set-MailboxAutoReplyConfiguration -identity $Email -AutoReplyState Enabled -InternalMessage $message
I'm no expert in either PowerShell or Exchange but this might help you.

How to get a PowerShell do-while loop to print on the first iteration before looping [duplicate]

This question already has an answer here:
PowerShell output is crossing between functions
(1 answer)
Closed 3 years ago.
ISSUE:
My issue is that I have a very simple do..while loop. However, it does not print the output of the Get-ADPrincipalGroupMembership query on the first iteration. For example, I run the script and enter a username then click enter. Instead of my expected result which is print the memberships, it loops around and asks for username again without printing the results of the first inputted username. Once I enter the username the second time in the loop and click enter then it prints the results of the first input and the results of the second input. Any time after the second iteration the script works fine and actually prints the results correctly after I provide the input. Below is the script in question.
EXPECTED RESULT:
The code below is simply supposed to ask the user for a username then run a query in AD to list the memberships of a given user. After providing the memberships of a user the script should ask for another user and repeat the process until the user enters "exit" and the script exits out.
CODE SNIPPET:
do {
$user = Read-Host -Prompt 'Enter the username of the user';
Get-ADPrincipalGroupMembership $user | select name;
} while ($user -ne 'exit');
Stop-Process -Id $PID;
Just got an answer form anther forum. The simplest solution to this is to simply add "| Out-String" after "| select name". The updated example is below.
do {
$user = Read-Host -Prompt 'Enter the username of the user'
Get-ADPrincipalGroupMembership $user | select name | Out-String
} while ($user -ne 'exit')
stop-process -id $PID
The property Name is an object from type string:
name Property System.String name {get;}
So you may simplify a bit:
do {
$user = Read-Host -Prompt 'Enter the username of the user'
(Get-ADPrincipalGroupMembership -Identity $user).name
} while ($user -ne 'exit')
stop-process -id $PID
Best regards,
Ivan

Trying to figure out how to insert initials + surname in alias for Exchange user with Powershell

Previously my script asked what the preferred username will be. Now I want to generate the username based on initials and surname.
However the alias for the e-mail is a bit different and that's the part where it doesn't work as I want to.
When an user has three initials the alias will be set to: jh.d.smith#domain.com, instead of jhd.smith#domain.com.
I don't know how to set this the proper way. Tried different methods.
$IMsg = 'Please enter initials'
$Initials = '{0}.' -f ((Read-Host -Prompt $IMsg).ToUpper().ToCharArray() -join '.')
$Firstname = Read-Host -Prompt 'Please enter firstname'
$Firstname = (Get-Culture).textinfo.totitlecase($Firstname.tolower())
$Lastname = Read-Host -Prompt 'Please enter surname'
$Lastname = $Lastname.ToLower() -replace ($Lastname.split(' ')[-1]), (Get-Culture).textinfo.totitlecase(($Lastname.split(' ')[-1]))
$UserID = $Initials.Replace('.','') + $lastname ## The username has to be without a dot, for example: jhdsmith.
$aliasid = $UserID.Insert(2,'.') ## This is for the e-mail alias.
Enable-Mailbox -Identity "$UserID#int.domain.com" -Alias $AliasID -Database DOMAIN-MAIL\DOMAIN-Store\Maildatabase01 | Out-Null
I think the easiest way is to do the following at the alias part:
$aliasid = $Initials.Replace('.','') + "." + $Lastname
I would also trim spaces like the following, in case someone has a lastname with spaces etc:
$UserID = (($Initials.Replace('.','') + $lastname).replace(" ","")).ToLower() ## The username has to be without a dot, for example: jhdsmith.
$aliasid = (($Initials.Replace('.','') + "." + $Lastname).Replace(" ","")).ToLower() ## This is for the e-mail alias.
This is beyond what you were after, but hopefully will be a good learning exercise :) If you deal with things logically, you don't need to use Replace(), ToCharArray() or Split()...
Starting point here is by ensuring that you input variables are all lowercase, alpha chars (a-z only), this can be achieved like this:
$Initials_input = (Read-Host -Prompt 'Please enter initials').tolower() -replace "\W"
The special bit here is -replace "\W" this uses regex word-characters to remove any non-word character (numbers/spaces/special chars) leaving only A-Z or a-z.
Then to make it easy to convert to TitleCase or UpperCase later on I have also used .tolower().
Once you know the state of all your inputs, you can simply build the strings to your desired format and convert to the required case.
Note that I don't change the input variables, they stay as-is. This way they are a known quantity, and you don't need to undo changes that are required by one variable to create another:
$Initials_input = (Read-Host -Prompt 'Please enter initials').tolower() -replace "\W"
$Firstname_input = (Read-Host -Prompt 'Please enter firstname').tolower() -replace "\W"
$Lastname_input = (Read-Host -Prompt 'Please enter surname').tolower() -replace "\W"
$Firstname = (Get-Culture).textinfo.totitlecase($Firstname_input)
$Lastname = (Get-Culture).textinfo.totitlecase($Lastname_input)
$Initials = $Initials_input.ToUpper()
$UserID = $Initials_input + $Lastname_input
$AliasID = $Initials_input + '.' + $Lastname_input
As you can see there's much less code, and it's easy to see what format your outputs will be.
Example input:
$Initials_input = 'jxz'
$Firstname_input = 'john'
$Lastname_input = 'smith'
Gives outputs:
$Firstname = John
$Lastname = Smith
$Initials = JXZ
$UserID = jxzsmith
$AliasID = jxz.smith

Powershell while loop

The below code keeps getting stuck in a loop when it gets to
$choice = read-host "Are you sure you want to disable the following user? (Y/N)" "$name"
I type in y and it keeps looping that question.
I've tried a do while & single IF statement. Any ideas on how to stop this loop?
$choice = ""
$User = read-host "enter username"
$Name = Get-ADuser -Identity $Username | Select-Object Name
while ($choice -notmatch "y/n"){
$choice = read-host "Are you sure you want to disable the following user? (Y/N)" "$name"
If ($Choice -eq"Y"){
Disable-ADAccount $Username
}
}
You need to use the pipe for an or statement to work not a slash
This...
while ($choice -notmatch "y/n"
...should be this...
while ($choice -notmatch "y|n"
This is wrong, because you do not have a populated variable in the posted code to use...
Disable-ADAccount $Username
... based on your code, it should be this...
Disable-ADAccount $User
No need to seperate the variable in the choice statment. Just do this.
$choice = read-host "Are you sure you want to disable the following user? (Y or N) $name"
Example:
$choice = ""
$User = read-host "enter username"
$Name = $User
while ($choice -notmatch "y|n")
{
$choice = read-host "Are you sure you want to disable the following user? (Y/N) $Name"
If ($Choice -eq "y")
{ $User }
}
enter username: test
Are you sure you want to disable the following user? (Y/N) test: u
Are you sure you want to disable the following user? (Y/N) test: u
Are you sure you want to disable the following user? (Y/N) test: y
test
enter username: test1
Are you sure you want to disable the following user? (Y/N) test1: h
Are you sure you want to disable the following user? (Y/N) test1: h
Are you sure you want to disable the following user? (Y/N) test1: n