PowerShell: After renaming AD Object, Move-Mailbox cannot locate object - powershell

So in my script, when a user changes their name, I rename their AD object accordingly, change their Exchange (2007) properties, and then based on those changes, I change the info store that it is in.
I store the new DistinguishedName in $newDN when retrieving the mailbox, explicitly try to use DC01.domain.local, and then when I attempt to do the move, it tries searching on DC02.domain.local, therefore not finding the object due to replication lag and receive this error below. Anyone have any ideas on this? Many thanks!
StatusCode : -1056749240
StatusMessage : Error occurred in the step: Approving object. Failed to open object 'LDAP://DC02.domain.local/CN=di matteo\, robert,OU=Users,DC=domain,DC=local' with error: There is no such object on the server.
$mailbox = Get-Mailbox -ID $newDN `
-DomainController DC01.domain.local
$mailbox | Move-Mailbox `
-TargetDatabase $targetIS `
-Confirm:$False `
-DomainController DC01.domain.local `
-GlobalCatalog DC01.domain.local
Sometimes the move works, but when it doesn't, it leaves the SourceDomainController property empty (like below), where as if it does work, it populates it correctly with DC01.domain.local.
SourceServer : CCR.domain.local
SourceDatabase : CCR\IS1\IS1
SourceGlobalCatalog : DC01.domain.local
SourceDomainController :
TargetGlobalCatalog : DC01.domain.local
TargetDomainController : DC01.domain.local
TargetMailbox :
TargetServer : CCR.domain.local
TargetDatabase : CCR\IS2\IS2
Baffled.

Well, I've got no idea why I'm getting the results that I am, but my workaround is here...Like I said before, I query/write all my AD changes to 'DC01.domain.local' But now, when I call my function, I do my mailbox lookup on 'DC02.domain.local'. If the lookup fails, increment the counter, sleep for about 20 seconds, and then retry. My initial testing, it has only had to loop once.
$dc = "DC01.domain.local"
Function moveDB ($targetIS, $newDN, $counter) {
$dn = (Get-Mailbox -ID $newDN -DomainController $dc).DistinguishedName
If (!(Get-Mailbox $dn -DomainController "DC02.domain.local")) {
$counter++
If ($counter -le 4) {
Write-Host "`nPlease wait while I search for the mailbox object...`n" -ForegroundColor Yellow -BackgroundColor Red
Start-Sleep -Seconds 20
moveDB $targetIS $dn $dbCounter
}
Else {
Write-Host "Mailbox was not moved! Please move manually to $targetIS..." -ForegroundColor Yellow -BackgroundColor Red
return
}
}
Else {
$dn | Move-Mailbox `
-DomainController $dc `
-GlobalCatalog $dc `
-TargetDatabase $targetIS `
-Confirm:$False
}
}

Related

Updating Active Directory via PowerShell

Hallo I got a question with my update script for my active directory
I am trying to update a user using .csv document
It’s for my understanding very simple but there is an error which I cant find out why it occurs.
My Script:
#Get CSV content
$CSVrecords = Import-Csv "C:\scripts\test.csv" -Delimiter ";"
#Create arrays for skipped and failed users
$SkippedUsers = #()
$FailedUsers = #()
#Loop trough CSV records
foreach ($CSVrecord in $CSVrecords) {
$upn = $CSVrecord.UserPrincipalName
$user = Get-ADUser -Filter "userPrincipalName -eq '$upn'"
if ($user) {
try {
$user | Set-ADUser -Department $CSVrecord.Department -Company $CSVrecord.Company -ErrorAction STOP
}
catch {
$FailedUsers += $upn
Write-Warning "$upn user found, but FAILED to update."
}
}
else {
Write-Warning "$upn not found, skipped"
$SkippedUsers += $upn
}
}
The Date that I am trying to use for the Update:
UserPrincipalName
Department
Company
test.nikola#test.local
Test
123
The Error message that I get: user found, but FAILED to update
Maybe I am blind but i cant find the error ...
As mentioned in the comments, your catch block is hiding all terminating exceptions. Since you never output or inspect the given exception, there's no way to tell what went wrong.
Change it to:
try {
$user | Set-ADUser -Department $CSVrecord.Department -Company $CSVrecord.Company -ErrorAction STOP
}
catch {
$FailedUsers += $upn
Write-Warning "$upn user found, but FAILED to update: $_"
}
Inside the catch block, $_ will refer to the exception that was caught, so at least you now get a chance to see the underlying error message.

Statements has no effect (if/else) in PS

I'm working on a script that gets executed only if X account is found, but is not working as intended the if/else statements get bypassed and the code gets executed anyways. What am i doing wrong?
$Account = "XXXX"
Get-LocalUser -name $Account
if (($Account) -eq $true) {
} else {
Write-host -foreground cyan "I found it"
}
exit
If i ran the script as is it will output the text on the console even tho "XXX" account is not present, could something like that can be done?
This should do it:
$Account = "XXXX"
$AccountObject=Get-LocalUser -name $Account -ErrorAction SilentlyContinue
if (($AccountObject)) {
Write-host -foreground cyan "I found it"
} else {
Write-host -foreground cyan "No luck"
}
The issue with the sniplet provided - the return of Get-LocalUser was not used. Instead you were using a string value which is always set therefore true - as you set it to 'XXXX' in your first line.
As Bill_Stewart explains, the reason that the else block is reached is because ($Account) -eq $true evaluates to $false unless the account name is "true".
In order to test whether Get-LocalUser succeeded or failed to retrieve the user account, you can instead inspect the $? automatic variable - it will have a value of $false only if the previous command threw an error:
$AccountName = "nonExistingUser"
# Try to fetch existing user account, don't show any errors to the user
$UserAccount = Get-LocalUser -Name $AccountName -ErrorAction SilentlyContinue
# Test if the call was successful
if($?) {
Write-Host "Found account named '$AccountName'!" -ForegroundColor Cyan
$UserAccount
} else {
Write-Host "No account named '$AccountName' was found ..." -ForegroundColor Magenta
}

How do I delete user in Active Directory through Powershell?

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

Check If Azure Resource Group Exist - Azure Powershell

I'm trying to verify if ResourceGroup exist or not so i thought that following code should return true or false, but it doesn't output anything.
$RSGtest = Find-AzureRmResource | Format-List ResourceGroupName | get-unique
$RSGtest -Match "$myResourceGroupName"
Why am I not getting any output?
Update:
You should use the Get-AzResourceGroup cmdlet from the new cross-plattform AZ PowerShell Module now. :
Get-AzResourceGroup -Name $myResourceGroupName -ErrorVariable notPresent -ErrorAction SilentlyContinue
if ($notPresent)
{
# ResourceGroup doesn't exist
}
else
{
# ResourceGroup exist
}
Original Answer:
There is a Get-AzureRmResourceGroup cmdlet:
Get-AzureRmResourceGroup -Name $myResourceGroupName -ErrorVariable notPresent -ErrorAction SilentlyContinue
if ($notPresent)
{
# ResourceGroup doesn't exist
}
else
{
# ResourceGroup exist
}
try this
$ResourceGroupName = Read-Host "Resource group name"
Find-AzureRmResourceGroup | where {$_.name -EQ $ResourceGroupName}
I am a PS newbie and I was looking for a solution to this question.
Instead of searching directly on SO I tried to investigate on my own using PS help (to get more experience on PS) and I came up with a working solution.
Then I searched SO to see how I compared to experts answers.
I guess my solution is less elegant but more compact. I report it here so others can give their opinions:
if (!(Get-AzResourceGroup $rgname -ErrorAction SilentlyContinue))
{ "not found"}
else
{"found"}
Explanation of my logic: I analyzed the Get-AzResourceGroup output and saw it's either an array with found Resource groups elements or null if no group is found. I chose the not (!) form which is a bit longer but allows to skip the else condition. Most frequently we just need to create the resource group if it doesn't exist and do nothing if it exists already.
I was also looking for the same thing but there was a additional condition in my scenario.
So I figured it out like this. To get the scenario details follow
$rg="myrg"
$Subscriptions = Get-AzSubscription
$Rglist=#()
foreach ($Subscription in $Subscriptions){
$Rglist +=(Get-AzResourceGroup).ResourceGroupName
}
$rgfinal=$rg
$i=1
while($rgfinal -in $Rglist){
$rgfinal=$rg +"0" + $i++
}
Write-Output $rgfinal
Set-AzContext -Subscription "Subscription Name"
$createrg= New-AzResourceGroup -Name $rgfinal -Location "location"
Had a similar challenge, I solved it using the script below:
$blobs = Get-AzureStorageBlob -Container "dummycontainer" -Context $blobContext -ErrorAction SilentlyContinue
## Loop through all the blobs
foreach ($blob in $blobs) {
write-host -Foregroundcolor Yellow $blob.Name
if ($blob.Name -ne "dummyblobname" ) {
Write-Host "Blob Not Found"
}
else {
Write-Host "bLOB already exist"
}
}

Capturing errors in this Powershell script

I have this test script to change the Administrator password on a list of servers.
I have set the script to log errors if the server can't be ping'd or account can't be found etc. However in addtion to this i'd like to capture any other errors that take place and also add those to the log file. I know you can use the "Try and Catch" for error handling but havn't had any luck so far.
Would someone be kind enough to show how to do it?
Here is the script
$date = Get-Date
$user = "Administrator"
$newpwd = "MyPassword"
$servers = gc C:\servers.txt
foreach ($server in $servers)
{
$ping = new-object System.Net.NetworkInformation.Ping
$Reply = $null
$Reply = $ping.send($server)
if($Reply.status -like 'Success')
{
$Admin=[adsi]("WinNT://" + $server + "/$user, user")
if($?)
{
$Admin.SetPassword($newpwd)
if($?)
{Add-Content -path C:\Audit\logs\servers-reset.csv -Value "$server, Succsess the $user password was changed. , $date"}
else
{Add-Content -path C:\Audit\logs\servers-reset.csv -Value "$server, Error: FAILED to change the password. , $date"}
}
else
{
Add-Content -path C:\Audit\logs\servers-reset.csv -Value "$server, Error: The $user user account was not found on the server. , $date"}
}
else
{
Add-Content -path C:\Audit\logs\servers-reset.csv -Value "$server, Error: Ping FAILED could not connect. , $date"
}
If you want to write exceptions to the log right after they were thrown, you could use a trap. Add something like this to you script:
trap [Exception] {
#Add message to log
Add-Content -Path test.csv -Value "$server, $($_.Exception.Message), $(Get-Date)"
#Continue script
continue;
}
That will log all exceptions (not all errors).
If you want all errors, you can access them using $Error. It's an arraylist containing every error during your sessions(script). The first item $Error[0] is the latest error. This however, is not something that fits directly into an csv file without formatting it.