In PowerShell Exchange-online you can get the mailbox of a user from Get-Mailbox
If i then have the following user input.
$email = Read-Host -Prompt 'what email is it?'
How can i check the user input and see if it matches an existing mailbox and say "mailbox exists" if it exists, else the script should just stop running. How could this be done ?
There are a number of ways to approach this. One way it to store the mailbox search result into a variable. Then simply check if the variable actually stored anything.
$email = Read-Host -Prompt 'what email is it?'
$mailbox = Get-Mailbox $email -ErrorAction SilentlyContinue
if ($mailbox) {
"Mailbox exists"
} else {
Exit
}
-ErrorAction SilentlyContinue is used to suppress the error that would be returned when the mailbox is not found.
A more sophisticated approach would be to catch the exception and take action accordingly.
$email = Read-Host -Prompt 'what email is it?'
try {
$mailbox = Get-Mailbox $email -ErrorAction Stop
"Mailbox Exists"
} catch [System.Management.Automation.RemoteException] {
Exit
}
Related
I'm looking to create a simple powershell script that will import the user's first name from file, prompt to create a new password and loop on error when the password doesn't meet the password requirement based on the "ErrorVariable" if possible. If not, please advise.
# import user firstname from file
$firstname = $(Get-Content "C:\tmp\local\firstname.txt")
# prompt user for new password
$password = Read-Host "Hello, $firstname!! Please change your local admin account password. (Requirements: At least 8-characters, 1-Cap Letter, 1-Number) " -AsSecureString -Erroraction silentlycontinue -ErrorVariable PasswordError
# create new password
$password = $password
Get-LocalUser -Name "$firstname" | Set-LocalUser -Password $password -Erroraction silentlycontinue -ErrorVariable PasswordError
If ($PasswordError)
{
"Unable to update the password. The new password does not meet the length or complexity."
}
If (-Not $PasswordError)
{
"Password updated successfully!!"
See script above.........
Think you could simply use try/catch - e.g.:
try {
Set-LocalUser -Name $firstname -Password $password -Erroraction:stop
write-host "Password updated successfully!!"
}
Catch {
write-error $_
}
If the operation succeeded you will get "Password updated successfully!!", otherwise it returns the error.
I am writing the script which should validate the user in the active directory and gets some AD information. I am struggling with the error handling in this script:
$user = (Read-Host -Prompt 'Enter your network id').ToUpper()
#check if the user exists in the AD database
$userid= Get-ADUser $user | Select SamAccountName
$userid = $user
if (($user -match $userid)) {
Write-Host $user "exists in AD"
}else{
write-host "user cannot be found"
}
If someone who uses the script will put incorrect userId (which doesn't exist in AD), the script will throw an error message :
Get-ADUser : Cannot find an object with identity: 'DUMMY' under: 'DC=company,DC=com'.
At line:9 char:11
+ $memoid = Get-ADUser $user | Select SamAccountName
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (DUMMY:ADUser) [Get-ADUser], ADIdentityNotF
oundException
+ FullyQualifiedErrorId : ActiveDirectoryCmdlet:Microsoft.ActiveDirectory.Management.
ADIdentityNotFoundException,Microsoft.ActiveDirectory.Management.Commands.GetADUser
Even though incorrect userID was entered, I receive
= DUMMY exists in AD
How can I turn this exceptional error message into my custom message - "The user doesn't exist in AD"? Thank you in advance
For this, it is better not to use the -Identity parameter (which you imply in your code by using Get-ADUser $user)
Try
$userID = Read-Host -Prompt 'Enter your network id'
# check if the user exists in the AD database
# this will either return an ADUser object or $null
$user = Get-ADUser -Filter "SamAccountName -eq '$userID'" -ErrorAction SilentlyContinue
if ($user) {
Write-Host "$($user.SamAccountName) exists in AD" -ForegroundColor Green
}
else{
Write-Host "user $($user.SamAccountName) cannot be found" -ForegroundColor Red
}
You need to catch the exceptions using try/catch
In the error message, it is telling that "cannot find that object"
So, your first approach is to check whether the user exists or not in the If statement and then put them in try/catch like below
try{
$user = (Read-Host -Prompt 'Enter your network id').ToUpper()
#check if the user exists in the AD database
$userid= Get-ADUser $user | Select SamAccountName
$userid = $user
if (($user -match $userid)) {
Write-Host $user "exists in AD"
}else{
write-host "user cannot be found"
}
}
catch
{
#Your Custom Message in case of the error is coming in Std Out . $_.Exception.Message will catch the exact error message.
"Error Message: "+ "$_.Exception.Message"
}
The statement: $userid = $user needs to be deleted. As is it insures that you always have a match.
Next place your call to Get-ADUser in a Try/Catch construct to catch the error.
$user = (Read-Host -Prompt 'Enter your network id').ToUpper()
#check if the user exists in the AD database
Try {
$userid= Get-ADUser $user -EA "STOP" | Select SamAccountName
Write-Host $user "exists in AD"
}
Catch {
#*** Process errors here ***
write-host "user cannot be found"
Exit
}
#Continue your script here
Note: I don't have access to a Server so this is untested but should work in theory!
HTH
I have to delete users from my AD through Powershell. Powershell has to ask me who I want to delete, once I type in the username it should delete the account. Also when Powershell succesfully deleted the account or it should give me a message.
I'm kind of noob at this, but here is my code:
function aduser-remove($userremove){
Remove-ADUser -Identity $delete
if ($delete -eq $userremove){
return $true
}
else {
return $false
}
}
$delete = Read-host "Which user do you want to delete? (Type in username)."
aduser-remove $delete
if ($userremove -eq $true){
Write-Host $delete "deleted succesfully!" -ForegroundColor Green
}
elseif ($userremove -eq $false){
Write-Host "An error occured by deleting" $delete -ForegroundColor Red
}
else {
Write-Host $delete "does not exist." -ForegroundColor DarkGray
}
The result here is that Powershell does ask if I want to delete the account and it works. But Powershell keeps giving me the else message instead of the if message. Deleting the account was succesfull.
I have no idea what to now or if I'm missing something (I bet I am otherwise it would work).
I hope you guys can help me!
As commented, your code uses variables in places where they do not exist.
Also, I would recommend trying to find the user first and if you do, try and remove it inside a try/catch block, as Remove-ADUser creates no output.
Below a rewrite of your code. Please note that I have changed the name of the function to comply with the Verb-Noun naming convention in PowerShell.
function Remove-User ([string]$userremove) {
# test if we can find a user with that SamAccountName
$user = Get-ADUser -Filter "SamAccountName -eq '$userremove'" -ErrorAction SilentlyContinue
if ($user) {
try {
$user | Remove-ADUser -ErrorAction Stop -WhatIf
return $true
}
catch {
return $false
}
}
# if we get here, the user does not exist; returns $null
}
$delete = Read-host "Which user do you want to delete? (Type in username)."
# call your function and capture the result
$result = Remove-User $delete
if ($result -eq $true){
Write-Host "User $delete deleted succesfully!" -ForegroundColor Green
}
elseif ($result -eq $false){
Write-Host "An error occured while deleting user $delete" -ForegroundColor Red
}
else {
Write-Host "$delete does not exist." -ForegroundColor DarkGray
}
Note also that I have put in the -WhatIf switch. This switch ensures you will only get a message of what would happen. No user is actually deleted. Once you are satisfied the code does what you want, remove the -WhatIf switch.
Hope that helps
If you have rsat installed https://www.microsoft.com/en-us/download/details.aspx?id=45520
remove-aduser https://learn.microsoft.com/en-us/powershell/module/addsadministration/remove-aduser?view=win10-ps
I need assistance creating a PowerShell script to expire a users account and add an Out of Office Message to Exchange for 30 days after the expiration date. Below is what I have so far:
Param(
$mailbox = $(Read-Host "you must enter the first part of the email address"),
$StartTime = $(Read-Host "Please enter the start date and time of account expiration in MM/DD/YYYY HH:MM:SS"),
$Username = $(Read-Host "please enter the AS400 username"),
$EndTime = $StartTime.AddDays(30)
)
Set-ADAccountExpiration -Identity $Username -DateTime $StartTime;
Set-MailboxAutoReplyConfiguration -Identity $mailbox -AutoReplyState Scheduled -StartTime $StartTime -EndTime $EndTime -ExternalMessage "The Person you are trying to contact is no longer employed by the Company" -InternalMessage "The Person you are trying to contact is no longer employed by Company XYZ for further assistance please contact the your local Store."
Method invocation failed because [System.String] does not contain a method named 'AddDays'.
How do I create the methods or is there an easier way?
Read-Host returns a string. String objects don't have a method AddDays(). You need to make $StartTime a DateTime value.
Change this:
Param(
...
$StartTime = $(Read-Host "..."),
...
)
into this:
Param(
...
[DateTime]$StartTime = $(Read-Host "..."),
...
)
Note that this only works, because input strings in the format you're asking for can be cast to DateTime. Otherwise you'd need to actually parse the string.
I had some surprisingly similar code written for something a while back, I can't remember if this worked fully and I am unable to test right now, but you should at least be able to get an idea of how parsing the inputs and ensuring everything is valid is done here.
I've changed it around a bit to fit your use better, if the SamAccountName in AD is the same as the Email Alias then you just need to specify Mailbox and StartTime at minimum, it will "autodiscover" the AD account.
Any questions please let me know - and if there's an issue running i'll take a look tomorrow when i'm back in work.
Function Set-LeaverAccount {
Param(
[string]$MailBox = $null,
[string]$StartTime = $null,
[string]$UserName = $null,
[string]$ExternalMessage = "The person you are emailing has left the company, please contact admin#company.com for more details",
[string]$InternalMessage = $null,
[uint16]$OutOfOfficeDays = 30
)
#region Parse Mailbox
$MailBoxAlias = $MailBox
if (!(Get-Mailbox $MailBox -EA SilentlyContinue)){
do {
$Input = Read-Host "Email Alias"
$MailBox = Get-Mailbox $Input -EA SilentlyContinue
} while (!$MailBox)
Write-Host "Mailbox of $($MailBox.Name) Selected"
} else { $Mailbox = Get-Mailbox }
#endregion
#region Parse DateTime
if (![DateTime]::Parse($StartTime)){
do {
$Input = Read-Host "Date/Time of Expiration"
[DateTime]$StartTime = [datetime]::MaxValue
} while (![DateTime]::TryParse($Input,[ref]$StartTime))
Write-Host "Start Time Set To $($StartTime.ToString())"
}
$EndTime = $StartTime.AddDays($OutOfOfficeDays)
#endregion
#region Parse AD Username
if ($UserName -eq $null){
$UserName = $MailBoxAlias #If not set use alias as AD Name
}
if (!(Get-AdUser $UserName -EA SilentlyContinue)){
do {
$Input = Read-Host "AD Username"
$User = Get-AdUser $Input -EA SilentlyContinue
} while ($User.count -ne 1)
Write-Host "User $($User.Name) Selected"
} else {
$User = Get-AdUser $UserName
}
#endregion
if ($InternalMessage -eq $null) { $InternalMessage = $ExternalMessage }
Set-ADAccountExpiration -Identity $User -DateTime $StartTime
Set-MailboxAutoReplyConfiguration -Identity $Mailbox -AutoReplyState Scheduled -StartTime $StartTime -EndTime $EndTime -ExternalMessage $ExternalMessage -InternalMessage $InternalMessage
}
Set-LeaverAccount -MailBox "User01" -StartTime "12/02/16" -UserName "User_1" `
-ExternalMessage "The Person you are trying to contact is no longer employed by the Company" `
-InternalMessage "The Person you are trying to contact is no longer employed by Company XYZ for further assistance please contact the your local Store."
Alrighty, so I've got this much down.
# Prompts the script user to confirm that the account from
# $userName is indeed the one they want to Terminate
function Get-Confirmation {
[CmdletBinding(SupportsShouldProcess=$true)]
param (
[Parameter(Mandatory=$true)]
[String]
$userName
)
$confirmMessage = 'Are you sure that {0} is the user that you want to terminate?' -f $userName
$PSCmdlet.ShouldContinue($confirmMessage, 'Terminate User?')
}
# Code that populates $userName and starts the Termination process
if (Get-Confirmation -User $userName) {
# If confirmation == True: start Termination
# Copy user's security groups to $groups.txt in their user folder
Out-File $logFilePath -InputObject $userNameGroups.memberOf -Encoding utf8
# TODO: Remove $userName's security groups from AD Object
# Remove-ADGroupMember -Identity $_ -Members $userNameGroups -Confirm:$false
Copy-Item -Path "\\path\to\active\user\folder" `
-Destination "\\path\to\terminated\user\folder"
} else {
# Don't Terminate
# TODO: Restart script to select another user
}
So my question is: how do I satisfy the TODO in the else statement? I've searched online, but the only thing that has come up is restarting the computer. I just want the script to be re-run. Is it as simple as ./scriptName?
Rather than "Restarting" your script you could check that the input is correct before even "Starting" your script, if all the input is correct there won't be any need to "Restart" :)
Here a Do-While loop is used to check that a username exists in AD before proceeding to the script below:
$message = "Please enter the username you'd like to terminate"
Do
{
# Get a username from the user
$getUsername = Read-Host -prompt $message
Try
{
# Check if it's in AD
$checkUsername = Get-ADUser -Identity $getUsername -ErrorAction Stop
}
Catch
{
# Couldn't be found
Write-Warning -Message "Could not find a user with the username: $getUsername. Please check the spelling and try again."
# Loop de loop (Restart)
$getUsername = $null
}
}
While ($getUsername -eq $null)
# Do-While succeeded so username is correct
# Put script to run if input is correct here