Powershell - Use "Set-UnifiedGroup" to change more Groups - powershell

)
I wanna set hundred of Groups unvisible in the GAL. Is there a option to do this easy and fast? I am beginner in PowerShell ;) so keep care
Code is:
Set-UnifiedGroup -Identity "GroupName" -HiddenFromAddressListsEnabled $true
It is way to much to do this with all groups. Does anybody know another way?
Thank you so much!

You can iterate through all groups. First you need to get all groups. You can pass the return values to another Cmdlet with a pipe |.
There is a foreach-object loop. This means it will do something for every object returned by Get-UnifiedGroup or any other Cmdlet that returns objects
It should be something like that:
Get-UnifiedGroup | Foreach-Object {
Set-UnifiedGroup -Identity $_.Name -HiddenFromAddressListsEnabled $true
}
As I'm not able to test this be sure the property is $_.Name.
If you just use Get-UnifiedGroup you can see the properties name in the headline

Related

Creating PowerShell Script templates for easy group management

First of all thanks for the help to the other users, because of that I learned a lot.
I have a problem that there are lots of user templates in my company (Lots of different group settings depending operation). Because of that I want to make it easy for my colleges to assign user to Operations.
I think about a solution that My colleges enter the user and Group to a CSV file, then the script goes trough the CSV lines, detects the Operation, and go to the operations TXT file to get the group info, then add the user.
The files are:
UserAndOperation.csv and it includes 2 columns, first one is user second one is Operation
Then the TXT files are added, in them the Groups are added for every line (I also wanted to make only one Operation csv that first column is operation name and the second one is groups that has to be added, and separated by "," but that scared my eye :D ).
this is the Frankenstein code that I created:
Import-Csv ".\UserAndOperation.csv" | ForEach-Object {get-aduser $_.User | if($_.Operation = "Operation1"){
$Groups = Get-Content .\operation1.txt
foreach($group in $groups)
{Add-ADPrincipalGroupMembership -Identity $_.User -MemberOf $Group}
}
elseif ($_.Operaiton = "Operation2"){
$Groups = Get-Content .\operation2.txt
foreach($group in $groups)
{Add-ADPrincipalGroupMembership -Identity $_.User -MemberOf $Group}
}
And goes for each operation
}
It gives an error that it don't recognize the if and elseif statements.
I don't know how to proceed, could anyone help me with fixing it ?
Thanks and best Regards.
You can't pipe results into an if statement.
e.g.
get-aduser $_.User | if($_.Operation
You also have a typo in:
$_.Operaiton
I would suggest to clean up the code a bit by trying to put statements one per line, so as to not confuse yourself, outputting debug statements, etc..
As has already been pointed out, you can't shove arbitrary control flow statements like if into the middle of a pipeline statement.
Beyond that, your intended if/else approach will mean a lot of repeated code, making the script harder to maintain.
You could use a hashtable (#{}) to "map" the operation name to the relevant file name, this way you only need to write the loop to add the group memberships once:
# map the Operation column value to the relevant file path
$operations = #{
'Operation1' = 'path\to\operation1.txt'
'Operation2' = 'path\to\operation2.txt'
'Operation3' = 'path\to\operation3.txt'
}
Import-Csv ".\UserAndOperation.csv" | ForEach-Object {
$User = Get-ADUser $_.User
$Groups = Get-Content $operations[$_.Operation]
foreach($Group in $Groups){
Add-ADPrincipalGroupMembership -Identity $User -MemberOf $Group
}
}

How to move multiple users to multiple OUs importing users from CSV and filtering by department

New to powershell and scripting in general. Trying to improve automation in our onboarding process, we have to move multiple user accounts to multiple OUs every couple of months.
Import-Module ActiveDirectory
$dept1 = "OU=Path1,DC=SOMEWHERE,DC=OUTTHERE"
$dept2 = "OU=Path2,DC=SOMEWHERE,DC=OUTTHERE"
Import-Csv "C:\Scripts\Incoming.csv" | ForEach-Object {
$samAccountName = $_."samAccountName"
Get-ADUser -Identity $samAccountName -Filter {Department -eq "Dept1"} | Move-ADObject -TargetPath $dept1
Get-ADUser -Identity $samAccountName -Filter {Department -eq "Dept2"} | Move-ADObject -TargetPath $dept2
}
This actually moves ALL users with the department marked into the path I have set.. but I only want it to look at those users in the csv and then filter their departments from AD - not the CSV. I feel like I'm missing a step but I've searched everywhere and tried the get-help. I feel like I need to get the identity, then search/filter against something else but I'm not quite sure how. Would appreciate any help.
edit
Okay, if I run the following:
Get-ADUser -Filter {Department -eq "Dept1"} -Properties Department
It returns everyone that fits that property but how do I compare those to the $samAccountName and ONLY try to move those accounts or run the commands against the accounts on the list? When I ran the second half of the command it tried to move them all and failed.
Move-ADObject $samAccountName -Target $dept1
I feel dumb.
It's ok to feel dumb. You're not and everyone feels that way at times when trying to learn a new thing. You're also here asking for help, so you're ahead of the game compared to a lot of others.
#Lee_Daily's comment is correct that Get-ADUser doesn't support using both -Identity and -Filter in the same command. They're part of different parameter sets. You can tell from the syntax output of Get-Help Get-ADUser or the online docs. Both show 3 different sets of parameters and Identity and Filter are not in the same one. What's odd is that your original script should have thrown an error because you tried to use both in the same command. No need to worry about that now though.
Here's a typical way one might approach this task. First, you query the user's details including the department you want to make a decision on. Then, you write your condition and perform the appropriate action. Doing it this way means you're only querying AD once for each user in your CSV rather than twice like your original script which is good for script performance and load on your AD. The inside of your ForEach-Object loop might look something like this. Note the addition of -Properties department in Get-ADUser. We need to ask for it explicitly because department isn't returned in the default result set.
# all of this goes inside your existing ForEach-Object loop
$u = Get-ADUser -Identity $_.samAccountName -Properties department
if ($u.Department -eq 'Dept1') {
$u | Move-ADObject -TargetPath $dept1
} elseif ($u.Department -eq 'Dept2') {
$u | Move-ADObject -TargetPath $dept2
}
Now let's talk about some alternative ways you might approach this.
The first way sort of flips things around so you end up only calling Get-ADUser once total, but end up doing a lot more filtering/processing on the client side. It's not my favorite, but it sets things up to understand my preferred solution. In particular, the Get-ADUser call uses the -LDAPFilter parameter. LDAP filter syntax is a little strange if you've never seen it before and this particular example could use the more common -Filter syntax just as easily. But in the next example it would be much more difficult and learning LDAP filter syntax enables you to query AD from anything rather than just PowerShell.
# instead of immediately looping on the CSV we imported, save it to a variable
$incoming = Import-Csv "C:\Scripts\Incoming.csv"
# then we make a single AD query for all users in either Dept1 or Dept2
$users = Get-ADUser -LDAPFilter '(|(department=Dept1)(department=Dept2))' -Properties department
# now we filter the set of users from AD by department and whether they're in the CSV and do the moves as appropriate
$users | Where-Object { $_.department -eq 'Dept1' -and
$_.samAccountName -in $incoming.samAccountName } | Move-ADObject -TargetPath $dept1
$users | Where-Object { $_.department -eq 'Dept2' -and
$_.samAccountName -in $incoming.samAccountName } | Move-ADObject -TargetPath $dept2
The benefit of this method is the single AD round trip for users rather than one for each in the CSV. But there are a lot more local loops checking the samAccountNames in the results with the samAccountNames from the CSV which can get expensive cpu-wise if your CSV and/or AD is huge.
The final example tweaks the previous example by expanding our LDAP filter and making AD do more of the work. AD is ridiculously good at returning LDAP query results. It's been fine-tuned over decades to do exactly that. So we should take advantange of it whenever possible.
Essentially what we're going to do is create a giant 'OR' filter out of the samAccountNames from the CSV so that when we get our results, the only check we have to do is the check for department. The way I verbalize this query in my head is that we're asking AD to "Return all users where SamAccountName is A or B or C or D, etc and Department is Dept1 or Dept2. The general form of the filter will look like this (spaces included for readability).
(& <SAM FILTER> <DEPT FILTER> )
# Where <DEPT FILTER> is copied from the previous example and
# <SAM FILTER> is similar but for each entry in the CSV like this
(|(samAccountName=a)(samAccountName=b)(samAccountName=c)...)
So let's see it in action.
# save our CSV to a variable like before
$incoming = Import-Csv "C:\Scripts\Incoming.csv"
# build the SAM FILTER
$samInner = $incoming.samAccountName -join ')(samAccountName='
$samFilter = "(|(samAccountName=$samInner))"
# build the DEPT FILTER
$deptFilter = '(|(department=Dept1)(department=Dept2))'
# combine the two with an LDAP "AND"
$ldapFilter = "(&$($samFilter)$($deptFilter))"
# now make our single AD query using the final filter
$users = Get-ADUser -LDAPFilter $ldapFilter -Properties department
# and finally filter and move the users based on department
$users | Where-Object { $_.department -eq 'Dept1' } | Move-ADObject -TargetPath $dept1
$users | Where-Object { $_.department -eq 'Dept2' } | Move-ADObject -TargetPath $dept2
There are more efficient ways to build the LDAP filter string, but I wanted to keep things simple for readability. It's also a lot easier to read with better PowerShell syntax highlighting than StackOverflow's. But hopefully you get the gist.
The only limitation with using this method is when your incoming CSV file is huge. There's a maximum size that your LDAP filter can be. Though I'm not sure what it is and I've never personally reached it with roughly ~4000 users in the filter. But even if you have to split up your incoming CSV file into batches of a few thousand users, it's still likely to be more efficient than the other examples.

Is there a way to export the variable in a ForEach loop to my CSV output on each line

I am attempting to run a script against our AD that spits out the AD Users in a group, for all the groups in a list. Essentially attempting to audit the groups to find the users. I have a functioning script, except I have no way to determine when the output of one group ends, and where the output of the next begins.
I have tried looking for previous examples, but nothing fits exactly the method I am using, and with me just dipping my toes into powershell I have not been able to combine other examples with my own.
$groups = Get-Content "C:\Folder\File_with_lines_of_ADGroup_Names.txt"
foreach ($group in $groups) { Get-ADGroupMember -Identity "$group" | Where-Object { $_.ObjectClass -eq "user" } | Get-ADUser -Property Description,DisplayName | Select Name,DisplayName,Description,$group | Export-csv -append -force -path "C:\Folder\File_of_outputs.csv" -NoTypeInformation }
Right now the problem lies with getting the $group variable to be exported along with the Name, DisplayName, and Description of each user returned. This is the best way I can think of to tag each user's group and keep all the results in a single file. However, only the first line of results works which is the HEADERS of the CSV, and everything after it is either listed as "Microsoft.ActiveDirectory.Management.ADPropertyValueCollection"or simply blank after the first group of results.
Hoping someone can show me how to easily add my variable $group to the output for each user found for filtering/pivoting purposes.
Thanks and let me know if you have questions.
I believe what you are after are calculated properties on your select statement.
Select Name,DisplayName,Description,$group
Should Probably be something like
Select Name,DisplayName,Description,#{n='Group'; e={$group};}
See also https://serverfault.com/questions/890559/powershell-calculated-properties-for-multiple-values

Powershell - Add users to groups without ansi

I am looking for a solution to add users to groups in active directory after I have created their users accounts. Currently my powershell script has a few things lacking but I am going to tackle them one at a time.
In this cycle I trying to learn the best way to add groups to newly created user accounts. Is it best to copy from a template account (which I am having problems doing as I keep getting a blank account... Or should I manage all new user information directly in the script. Which is best practice?
In my research I see how this can be done with adsi.
I was hoping not to use this method unless I have to. what I was hoping for was something like this. with Get-ADUser, Set-ADUser, Set-ADObject, Get-ADObject, or similar commands.
$user=get-aduser 'abc user'
$userModify=Set-aduser $user
$groups=get-aduser $tmplateUser | select -ExpandProperty memberof
# or groups could come from an array, I have not decided which is best.
foreach ($Group In $groups)
{
$usermodify.memberof.add -identity $Group -member $user
}
Does anyone have any suggestions or examples?
if you can use the 'ActiveDirectory' module then you can try:
Import-Module ActiveDirectory
This will show you the cmdlets available for managing groupmembership.
Get-Command -Verb add -Noun *group*
This will show you examples of the cmdlet.
Help cmdletname -examples
There are many ways to create users, most use information stored in a csv file as input to say a cmdlet like New-ADUser.
The foreach construct will depend upon which cmdlet you choose to use.
$groups = Get-ADUser $tmplateUser -Properties memberof |
Select-Object -ExpandProperty memberof
foreach ($group in $groups)
{
Add-ADGroupMember -Identity $group -Members $newuser
}

Lync Powershell enable group members

I'm trying to automate enabling members of a group for Enterprise Voice, I have the following (pretty rough I know), which work if there's only a single member:
$telephoneNumber = Get-ADGroupMember -Identity "LyncEnterpriseVoice" | Get-ADUser -Properties telephoneNumber | Select-Object -ExpandProperty telephoneNumber
$ext = Get-ADGroupMember -Identity "LyncEnterpriseVoice" | Get-ADUser -Properties otherTelephone | Select-Object -ExpandProperty othertelephone
Get-ADGroupMember -Identity "LyncEnterpriseVoice" | foreach {Get-ADUser $_.SamAccountName | foreach {Set-CSuser -identity $_.UserPrincipalname –EnterpriseVoiceEnabled $True –LineUri "tel:$telephoneNumber;ext=$ext"}}
I can't figure out how to do a foreach otherTelephone and telephoneNumber. Can someone please point me in the right direction.
Not a definite answer, but should help you nonetheless:
You are calling Get-ADGroupMember -Identity "LyncEnterpriseVoice" three times in a row. Don't do that - it's inefficient and can even lead to inconsistencies if you don't get the same result back each time. Just call it once and assign it to a variable, then use that variable each time. This will also make your code much more readable, if you give that variable a good name.
Understand what you want to achieve exactly - what objects are you collecting, what properties do they have and what do you want to iterate over? I can barely get that from your code and it seems you don't have a solid understanding of it either. Once you understand that, the rest is easy.
Edit:
I'm not sure what you mean by "I get the results I want". I'm pretty sure your variables do not contain what you think they do. It's helpful to build a script line by line - examining for each step what objects you are dealing with. Otherwise you just make assumptions and you will inevitably be wrong often.
For example in line 1, you seem to get an array of telephone numbers and in line 2 an array of additional phone numbers ($telephoneNumber and $ext). But in line 3 you use these complete arrays, instead of a single element, to build that LineUri string for each user, which can't possibly be correct.
Also in line 3 you use AD user objects as input and then do a foreach and get get the AD user object again for each user - a clear sign that you are not aware of the objects you are dealing with.
So for example:
Get the users we want to manipulate, including the telephone numbers. Otherwise you are dealing with three separate arrays and don't know how to match up everything - it's just messy.
$users = Get-ADGroupMember -Identity LyncEnterpriseVoice | Get-ADUser -Properties telephoneNumber, othertelephone
Let's see what we have:
$users
Ok, it's an array of objects with all the information we need, but just out of curiosity, what kind of objects are they exactly?
$users[0].GetType()
Not very surprisingly, they are ADUser objects. Let's set some properties:
$users | foreach { Set-SCUser -Identity $_.UserPrincipalName –EnterpriseVoiceEnabled $true –LineUri "tel:$($_.telephoneNumber);ext=$($_.othertelephone)" }
Note the subexpressions $(...) in the string - these are necessary, because else the variable $_ would be expanded and the rest would literally be ".telephoneNumber".
One additional thing: you write "tel:...;ext=..." which is inconsistent and seems weird - maybe a typo?