set-mailboxautoreplyconfiguration breaks scandinavian characters - powershell

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.

Related

Add smtp Proxy Addresses from users listed in a text file using PowerShell

I am trying to create a simple script to add Proxy Addresses to the AD field using PowerShell.
I was able to get it working using this, but now I am at a roadblock on how I can do this importing the usernames from a text file.
$Username = Read-Host -Prompt "Enter the username'
Set-AdUser $Username -add #{ProxyAddresses = "smtp:$Username#example.com,smtp:$Username#marketing.example.com" -split ","}
What I want to do now is instead of prompting for a username to be entered I just want to have a text file with username like this.
Text File Of Usernames: These will all be on a separate line. I am not sure how to format that way on here.
jallen
sdiggs
gdavis
mhyde
twhite
I am confused how to go forward with this. To my understanding I want to use Get-Content to create the username array and then for each line in the text file add the proxy addresses.
$Username = Read-Host -Prompt "Enter the username'
Set-AdUser $Username -add #{ProxyAddresses = "smtp:$Username#example.com,smtp:$Username#marketing.example.com" -split ","}
I want to remove the need for user input and import the username variables from a text file.
Assuming you have the txt file with each user in a new line as shown in your question, you're right, you can use Get-Content to read your file then you need to loop over each line:
(Get-Content path\to\yourfile.txt).Trim() | ForEach-Object {
try {
Set-AdUser $_ -Add #{ ProxyAddresses = "smtp:$_#example.com,smtp:$_#marketing.example.com".Split(",") }
}
catch {
# can do error handling here
Write-Error $_
}
}
The use of Trim() in this example is so it removes any excess of white space from the beginning and end of all lines.

Add User to Exchange In-placeHold/eDiscovery (In-Situ) with powershell

I'm currently encountering some problems with powershell, while creating scripts.
I want to add a User to our In-place-Hold / eDiscovery. I more or less found a workaround to adding a single User to the list, but I'm not sure if it works without losing data of the already existing In-Place-Hold users.
The goal is to add newly created users to an existing In-Place-Hold.
However, maybe its easier to understand with my code:
#All users that are already in the in-situ
$check = Get-MailboxSearch “In situ autotest"
foreach ($User in $ADUsers)
{
$Username = $User.username
$Firstname = $User.firstname
$Lastname = $User.lastname
if (Get-Mailbox -Identity $Username)
{
#If user does exist, output a warning message
Write-Warning "Benutzername $Username already existing on the Exchange Server."
}
else
{
Enable-Mailbox -Identity "$Username" -DomainController 'DC.domain.com'
}
#search for the user
$Add = Get-Mailbox -Identity "$Username"
$check.sources.add("$Add")
}
#write all users back into insitu mailbox
Set-Mailboxsearch -Name "In situ autotest" -Identity "In situ autotest" -SourceMailboxes $check.sources
Does someone know if there is an easier way to add a single user to the sourcemailboxes of Set-Mailboxsearch, without having to aplly everyone again?
Thank you guys very much in advance!

MapNetworkDrive credential escaping special characters problem

I am actually mapping network drive with pgina at boot,
the only problem is i can't escape special characters like :"'
I use args[1] as input, but special characters like " transfoms into something else, i need to use them raw because i need to mount a user folder even with passwords with special characters.
$user = $args[0];
$password = $args[1];
$user = $user.Trim();
$user= $user.ToLower();
Write-Output "$user | $password" > c:\SCRIPTS\TMP\lastlog.txt;
$PSnet = $(New-Object -ComObject WScript.Network);
$smbserver = "172.18.49.101";
$userFolder="\\$smbserver\$user";
$PSnet.MapNetworkDrive("Z:", $userFolder, $false, "smbserver\$userid", $password;

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

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)