trying to catch error with Add-QADGroupMember - powershell

I'm writing a script to bulk add users from a CSV, then add groups from another user.
It's working fine, except that some groups i'm not able to add (I get access denied when using the AD MMC - we have to get a different group to add them for us). The problem is that Add-QADGroupMember silently fails. I would like to somehow catch the error and list the groups that I have to get added by the different group.
I've tried try/catch, but it doesn't work... i'm at a loss.
Here is the code at the moment:
$users = Import-Csv .\UserList.csv
foreach ($user in $users) {
$SameAs = $user.SameAs
$UserGroups = (Get-QADUser $SameAs).MemberOf
foreach ($group in $UserGroups) {
Add-QADGroupMember $group -Member $user.SamAccountName |Out-Null
}
}
I'm just not able to get it to throw an error or exception when it fails to add a group.
Thanks for any help.

You have to set the erroraction to "stop".
I had the same problem with PowerCLI and all commands from there.
Try it so:
Add-QADGroupMember $group -Member $user.SamAccountName -ErrorAction Stop |Out-Null
or you can set the ErrorActionPreference global with
$ErrorActionPreference = "Stop"

Related

i want to know the life of a custom function in powershell

function delete_Users
{
Import-Module ActiveDirectory
$Users = Import-Csv C:\temp\test.csv
ForEach ($User in $Users)
{
# Retrieve user to make sure they exist.
$ADUser = Get-ADUser -Identity $User.sAMAccountName
If ($ADUser)
{
# Delete the user.
Remove-ADUser -Identity $User.sAMAccountName
}
}
}
I am trying to add this code in custom menu of powershell ISE.Can some one please let me knew how to do this. I tried this piece of code but it didn't worked for me.
#to add the function in custom menu option
$psISE.CustomMenu.Submenus.Add(“Run Custom Function”,{delete_Users},Ctrl+Shift+0)
Moreover what would be the life of that custom function? Would it remain there even after closing the session or after shutting down the server or is there any specific way to achieve this.
Thank you in Advance..

handle ADIdentityNotFoundException without stopping the program

I have to loop for each object in an input file, doing a Get-ADUser on each object, and I want to handle the ADIdentityNotFoundException error without stopping the loop. Is there a better way I can accomplish this (simplified for example's sake):
Import-Csv $input | Foreach-Object {
$manager = "BLANK"
if ($user = Get-ADUser $_."samaccountname" -properties * ) {
# I don't think I need this in an IF{} since the line below won't work
# so $manager will be equal to the last value set, "BLANK", but
# this makes it easier to understand what I want to happen
$manager = $user."manager"
# I need more properties (thus -properties *) but again just an example
}
}
In essence, if the Get-ADUser lookup is successful, set $manager = $user."manager"
If it is not successful, do not stop the loop, do not copy the value of the previous user, have $manager = "BLANK"(or whatever). The issue I have with the try/catch solutions, is that ADIdentityNotFoundException doesn't trigger the catch unless I add -ErrorAction Stop, which will cause the undesired result of the program terminating.
I'm not sure why your program would be terminating. Using the below sample code loops through all the users in the array. I have purposely entered an incorrect username into the second value of the array (position [1]):
$users = "username1", "username2", "username3" #username2 is purposely incorrect
foreach ($i in $users){
try{
$user = Get-ADUser -Identity $i -Properties * -ErrorAction Stop
Write-Host "Found"
}catch{
Write-Host "Not found"
}
}
my output is
found
not found
found

PowerShell try-catch exit loop before second try occurs

I'm trying to loop a list of users where it is unknown if it contains English or Swedish and in addition to this check I need to know if there is an account called "CMG*" before executing the main task.
The problem is that my first 'Try' runs the lines as expected but the second one is ignored, so it apparently exit the loop on 'continue' it seems.
Can you not have 2 sets of 'Try-Catch' inside an 'if' statement?
What I have tried is to flip the two sets of 'Try-Catch' and it results in whatever is first in the loop execute and the bottom one is ignored.
foreach($User in $Users){
if($User."ADattribute"){
try {
if(!(Get-MailboxFolderPermission -Identity "$($User.UserPrincipalName):\Calendar" | Where-Object User -like 'CMG*')){
Add-MailboxFolderPermission -Identity "$($User.UserPrincipalName):\Calendar" -User <SecretUser> -AccessRights Reviewer
}
continue
}
catch [System.Management.Automation.RemoteException] {
Write-Host ":\Calendar could not be found"
}
try {
if(!(Get-MailboxFolderPermission -Identity "$($User.UserPrincipalName):\Kalender" | Where-Object User -like 'CMG*')){
Add-MailboxFolderPermission -Identity "$($User.UserPrincipalName):\Kalender" -User <SecretUser> -AccessRights Reviewer
}
continue
}
catch [System.Management.Automation.RemoteException] {
Write-Host ":\Kalender could not be found."
}
}
}
I think you are missing the function of the keyword continue. When executing the continue keyword, the current iteration stops and it continues with the next iteration. So I think if you remove the continue keyword(s) that your script will work as excepted.
https://devblogs.microsoft.com/scripting/powershell-looping-the-continue-statement/

ADSI/System.DirectoryServices.DirectorySearcher result parsing

A trivial question, but hopefully really obvious for those who know.
Search constructor:
$Search = New-Object System.DirectoryServices.DirectorySearcher
(([adsi]"LDAP://ou=Domain Users,dc=example,dc=pri"),'(objectCategory=person)',
('name','employeeID'))
I want to exclude results where the employeeID attribute does not exist.
This works:
$users = $Search.FindAll()
ForEach ($u in $users) {
If ($u.properties.employeeid) {
Write-Host $($u.properties.name)
}
}
The following does not work - no output. However, when the IF statement is omitted, results are output.
ForEach ($user in $($Search.FindAll())) {
If ($user.properties.employeeID) {
Write-Host $($user.properties.name)
}
}
Is it a syntax issue in the second example, or do I just need to temporarily store results in an object before running conditional statements on them?
(To circumvent any discussion on why not use the ActiveDirectory module and Get-ADUser, it's for a user that cannot have the module installed on their workstation, nor be granted perms to invoke it via a PSSession on a host where it is installed.)
Update: found a slightly nicer way of doing the where clause:
$searcher.FindAll() | where { ($_.properties['employeeid'][0]) }
Just remove if statement and filter search results:
$users = $Search.FindAll() | Where-Object {-not [string]::IsNullOrEmpty($_.properties.employeeID)}

Checking if Distribution Group Exists in Powershell

I am writing a script to quickly create a new distribution group and populate it with a CSV. I am having trouble testing to see if the group name already exists.
If I do a get-distributiongroup -id $NewGroupName and it does not exist I get an exception, which is what I expect to happen. If the group does exist then it lists the group, which is also what I expect. However, I can not find a good way to test if the group exists before I try to create it. I have tried using a try/catch, and also doing this:
Get-DistributionGroup -id $NewGroupName -ErrorAction "Stop"
which makes the try/catch work better (as I understand non-terminating errors).
Basically, I need to have the user enter a new group name to check if it is viable. If so, then the group gets created, if not it should prompt the user to enter another name.
You can use SilentlyContinue erroraction so that no exception/error shows:
$done = $false
while(-not $done)
{
$newGroupName = Read-Host "Enter group name"
$existingGroup = Get-DistributionGroup -Id $newGroupName -ErrorAction 'SilentlyContinue'
if(-not $existingGroup)
{
# create distribution group here
$done = $true
}
else
{
Write-Host "Group already exists"
}
}
This should do the trick:
((Get-DistributionGroup $NewGroupName -ErrorAction 'SilentlyContinue').IsValid) -eq $true