Powershell-else in try/catch - powershell

I'm trying to write output when get-addomain succeded.
Try/catch writes output only if command fails
try {
get-addomain -Identity d.contoso.com
}
catch {
Write-Output "failed"
}
I tried following:
if (-not (get-addomain -Identity d.contoso.com))
{
return "failed"
}
else
{
write-output "ok"
}
and
If (get-addomain -Identity d.contoso.com )
{
Write-Output "ok"
}
Else
{
write-output "failed"
}
but in both cases got
get-addomain : Cannot find an object with identity: 'd.contoso.com' under: 'DC=ad,DC=contoso,DC=com'.

The tryblock runs until a error is getting thrown. If get-addomain doesn't end with an error, the try-case will run the following commands written inside the {}.
So one way would be to just say the output is ok if no error gets thrown:
try {
get-addomain -Identity d.contoso.com
Write-Output "ok"
}
catch {
Write-Output "failed"
}
But if you want to double check, you can still do the if check in the try-catch:
try {
If (get-addomain -Identity d.contoso.com )
{
Write-Output "ok"
}
Else
{
write-output "failed"
}
}
catch {
Write-Output "failed"
}

try{
$domain = Get-ADDomain -Identity d.contoso.com
Write-Output $domain
}catch{
Write-Output "Failed with message '$($_.Exception.Message)'"
}
When you use the AD CmdLets, it fails when a non-existing identity is specified. Therefore if the object you search for does not exist, you will end up in the catch. The first piece of code you wrote is actually correct if you wish to output the AD domain information.

Related

If error, skip to next in Powershell (Microsoft Teams)

Good evening,
I have written a piece of code in Powershell that takes a .csv file as input, and create a new
Microsoft Team with the channels and users in the .csv
The script is working, but i dont really like the part where i add the owners to the team. I recieve a list of ID's in the .csv file, but i can only add the owners with a mailadres. This would be a easy loop, but there are 3 possible domains that the user is connected to.
My goal is to have a piece of code that adds #domain1.nl to the ID that i get in the .csv, and try to add the user. if i receive a error because that address does not exist, it will try to add the owner with #domain2.nl and #domain3.nl added to it. If nothing works, it should give a Write-Host that says "This domain has to be added"
Below is the piece of code that works, but i think its not the best way to it and it could be improved.
#Adding the owners to the Team
if ($d.ID) {
$Error.Clear()
try {
$ID = $d.ID + "#domain1.nl"
Add-TeamUser -GroupId $GroupID -User $ID -Role Owner
} catch { "Error occured" }
if ($Error) {
$Error.Clear()
try {
$ID = $d.ID + "#domain2.nl"
Add-TeamUser -GroupId $GroupID -User $ID -Role Owner
} catch { "Error occured" }
if ($Error) {
$Error.Clear()
try {
$ID = $d.ID + "#domain3.nl"
Add-TeamUser -GroupId $GroupID -User $ID -Role Owner
} catch { "Error occured" }
if ($Error) {
Write-Host "This domain has to be added to the code"
}
}
}
}
Many thanks in advance!
Use try / catch inside a foreach loop:
$ok = $false
foreach ($domain in '#domain1.nl', '#domain2.nl', '#domain3.nl') {
try {
Add-TeamUser -GroupId $GroupID -User ($d.ID + $domain) -Role Owner
$ok = $true
} catch {
Write-Warning "Error occurred with domain $domain."
}
if ($ok) { break }
}
if (-not $ok) {
Write-Error 'This domain has to be added to the code'
}

Try/catch is not working with Start-Service

My problem is really simple (I think). To catch when a service cannot be started and throw a message. Really the only reason it should fail is if the service is disabled but I want to let the user know that. I saw this post but none of the answers seemed to help since they're talking about filtering the catch with if statements and I can't even seem to get a basic catch working like so:
Write-Host "Starting Services ..."
$svc = Get-Service -DisplayName "*lar*" | where { $_.Status -Like "Stop*" }
if ( $svc )
{
foreach ( $item in $svc )
{
Write-Host "Starting"$item.Name
try { Start-Service $item.Name
}
catch {
Write-Host "Could not start service:" $item.Name
}
}
}
I do get an error when running, but not my write-host message in the catch
Start-Service on a disabled service throws a non-terminating error. For catch to work, you need a terminating error. You can force the error to be terminating by using -ErrorAction Stop.
try {
Start-Service $item.Name -ErrorAction Stop
}
catch {
Write-Host "Could not start service:" $item.Name
}

Prompt for Credentials Repeatedly in Powershell

I have the below code which prompts for username and password, and if incorrect has the right exceptions that are caught in the catch statement. However, how do I ensure I repeatedly prompt for username and password until a correct one is entered?
Another question is how do I convert the password entered into a secure string. Any help is greatly appreciated.
$TS_Deploy_Group = "MYADGROUP"
$get_AD_Server = (Get-WmiObject -Class Win32_NetWorkAdapterConfiguration | Where-Object { $_.DNSDomain -like "***-**.contoso.com"}).DnsDomain
if ($get_AD_Server -ne $null)
{
$get_Nearest_DC = (Get-ADDomainController -DomainName $get_AD_Server -Discover -NextClosestSite).Name
$AD_Server = $get_Nearest_DC,$get_AD_Server -join "."
$cred = $host.ui.PromptForCredential("Authenticate to OSD:", "Enter your Operator Credentials", "", "")
}
else
{
[System.Windows.Forms.MessageBox]::Show("Please make sure you are connected to the Corporate Network")
}
Try
{
$ADauth = Get-ADGroupMember -Identity $TS_Deploy_Group -Recursive -Server $AD_Server -Credential $cred
}
Catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException]
{
[System.Windows.Forms.MessageBox]::Show("The user" +$cred.username+ "has not been found", "User not found")
}
Catch [Microsoft.ActiveDirectory.Management.ADServerDownException]
{
[System.Windows.Forms.MessageBox]::Show("Check the server name or IP configuration", "Error while contacting AD Server")
}
Catch [System.Security.Authentication.AuthenticationException]
{
[System.Windows.Forms.MessageBox]::Show("Please check the admin user name or password", "Invalid credentials")
}
if (($ADauth.name -Contains $cred.username) -ne $true) {
[System.Windows.Forms.MessageBox]::Show("The specified user is not member of the group:
$TS_Deploy_Group", "Unauthorized user")
exit
}
Finally
{
[System.Windows.Forms.MessageBox]::Show("Task Sequence Will Continue to the Next Step")
}
I would do something like this:
while($true)
{
Try
{
$ADauth = Get-ADGroupMember -Identity $TS_Deploy_Group -Recursive -Server $AD_Server -Credential $cred
break
}
Catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException]
{
[System.Windows.Forms.MessageBox]::Show("The user" +$cred.username+ "has not been found", "User not found")
$cred = $host.ui.PromptForCredential("Authenticate to OSD:", "Enter your Operator Credentials", "", "")
}
Catch [Microsoft.ActiveDirectory.Management.ADServerDownException]
{
[System.Windows.Forms.MessageBox]::Show("Check the server name or IP configuration", "Error while contacting AD Server")
}
Catch [System.Security.Authentication.AuthenticationException]
{
[System.Windows.Forms.MessageBox]::Show("Please check the admin user name or password", "Invalid credentials")
$cred = $host.ui.PromptForCredential("Authenticate to OSD:", "Enter your Operator Credentials", "", "")
}
}

Try/Catch Example

I understand Stackoverflow isn't a write your code for you forum, absolutely, but I'm finding it very difficult to find a good example of try/catch proper usage in Powershell. I have read up on fundamentals, and understand the theoretical concept, but execution I'm struggling with.
Here is a simple script that queries Active Directory:
do {
clear
Import-Module active*
"============ WhoIs Lookup ============="
Write-Host ""
$who = Read-Host "WhoIs";
$req = Get-ADUser -Identity $who
Write-Host ''
Write-Host "$who is " -NoNewline
Write-Host $req.Name -ForegroundColor Cyan
pause
} while ($run =1)
An example error is:
Get-ADUser : Cannot find an object with
identity: '5621521' under: 'DC=dcsg,DC=com'.
At C:\Tools\CSOCTools\Who_Is\whoIs.ps1:10
char:12
+ $req = Get-ADUser -Identity $who
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFoun
d: (5621521:ADUser) [Get-ADUser], ADIde
ntityNotFoundException
+ FullyQualifiedErrorId : ActiveDirecto
ryCmdlet:Microsoft.ActiveDirectory.Mana
gement.ADIdentityNotFoundException,Micr
osoft.ActiveDirectory.Management.Comman
ds.GetADUser
How would I catch this User Not Found error?
Simple example:
try {
Get-ADUser -Identity “bleh”
}
catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException]
{
Write-Warning “AD computer object not found”
}
For your case:
do {
clear
Import-Module active*
"============ WhoIs Lookup ============="
Write-Host ""
$who = Read-Host "WhoIs";
try {
$req = Get-ADUser -Identity $who
}
catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException]
{
Write-Warning “AD user object not found”
Write-Host ''
Write-Host "$who is " -NoNewline
Write-Host $req.Name -ForegroundColor Cyan
}
pause
} while ($run =1)
Edit: I put the Write-Host into the catch as you're eventually trying to reference to NULL when there's no object.
I got a very good example from here. For the exception types after the Catch (where I have two of them) I just grabbed them straight from the error message you provided. I haven't tried this out many times in my experience, let me know if it works for ya!
Try
{
do {
clear
Import-Module active*
"============ WhoIs Lookup ============="
Write-Host ""
$who = Read-Host "WhoIs";
$req = Get-ADUser -Identity $who
Write-Host ''
Write-Host "$who is " -NoNewline
Write-Host $req.Name -ForegroundColor Cyan
pause
} while ($run =1)
}
Catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException],[Microsoft.ActiveDirectory.Management.Commands.GetADUser]
{
# Error message here
}

Continue execution on Exception

Below is the script I want to execute. The issue here is once an exception occurs it stops executing, I used continue in the catch block but that did not work. How do I get it working even after an exception occurs it should loop in foreach.
I also used a while($true) loop but that went into infinite loop. How to go about it?
$ErrorActionPreference = "Stop";
try
{
# Loop through each of the users in the site
foreach($user in $users)
{
# Create an array that will be used to split the user name from the domain/membership provider
$a=#()
$displayname = $user.DisplayName
$userlogin = $user.UserLogin
# Separate the user name from the domain/membership provider
if($userlogin.Contains('\'))
{
$a = $userlogin.split("\")
$username = $a[1]
}
elseif($userlogin.Contains(':'))
{
$a = $userlogin.split(":")
$username = $a[1]
}
# Create the new username based on the given input
$newalias = $newprovider + "\" + $username
if (-not $convert)
{
$answer = Read-Host "Your first user will be changed from $userlogin to $newalias. Would you like to continue processing all users? [Y]es, [N]o"
switch ($answer)
{
"Y" {$convert = $true}
"y" {$convert = $true}
default {exit}
}
}
if(($userlogin -like "$oldprovider*") -and $convert)
{
LogWrite ("Migrating User old : " + $user + " New user : " + $newalias + " ")
move-spuser -identity $user -newalias $newalias -ignoresid -Confirm:$false
LogWrite ("Done")
}
}
}
catch {
LogWrite ("Caught the exception")
LogWrite ($Error[0].Exception)
}
You use try {...} catch {...} when you want to handle errors. If you want to ignore them, you should set $ErrorActionPreference = "Continue" (or "SilentlyContinue") as #C.B. suggested, or use -ErrorAction "SilentlyContinue" for the particular operation raising the error. If you want to handle errors from a certain instruction, you'd put that instruction in the try {...} catch {...} block, not the entire loop, e.g.:
foreach($user in $users) {
...
try {
if(($userlogin -like "$oldprovider*") -and $convert) {
LogWrite ("Migrating User old : " + $user + " New user : " + $newalias + " ")
move-spuser -identity $user -newalias $newalias -ignoresid -Confirm:$false
LogWrite ("Done")
}
} catch {
LogWrite ("Caught the exception")
LogWrite ($Error[0].Exception)
}
}
You seem to have placed the "catch" outside the loop body, so that aborts the loop. Put the catch inside the loop
Modified the code as below. Used the following piece of code after move-spuser -identity $user -newalias $newalias -ignoresid -Confirm:$false
if($?)
{
LogWrite ("Done!")
LogWrite (" ")
}
else
{
LogWrite ($Error[0].ToString())
LogWrite (" ")
}
Something that worked for me is to set the $ErrorActionPreference variable to stop, and then reset it back to continue in the catch block:
$e = $ErrorActionPreference
$ErrorActionPreference="stop"
try
{
#Do Something that throws the exception
}
catch
{
$ErrorActionPreference=$e
}
$ErrorActionPreference=$e;