how to concatenate multiple address in powershell - powershell

I have a list of users but I don't know each user email domain so I'm just wondering how can I concatenate all the domains from $alldomans at the end of their name one by one and try to find their employeeId.
For example, I'm doing like this right now and this is working but I'll have more than one email domain so I'm just wondering how can I pass the domain from my list one by one and try to find their employee Id?.
$EmployeeId= $policy.name | foreach { (Get-AzureADUser -ObjectId "$($_)#gmail.com").ExtensionProperty.employeeId}
I've tried it like this but still not working for some reason
$allDomains = #(
"gmail.com",
"yahoo.com",
"outlook.com"
"hotmail.com"
)
$EmployeeId= $policy.name | foreach { (Get-AzureADUser -ObjectId "$($_)#$allDomains").ExtensionProperty.employeeId}

You need an inner loop for the Domains:
$allDomains = #(
"gmail.com",
"yahoo.com",
"outlook.com"
"hotmail.com"
)
$EmployeeId = $policy.name | ForEach-Object {
foreach($domain in $allDomains) {
try {
$azUsr = Get-AzureADUser -ObjectId "$_#$domain" -ErrorAction Stop
# using `return` here so that if `$azUsr` could be found,
# we stop this inner loop and go to the next user
return $azUsr.ExtensionProperty.employeeId
}
catch {
Write-Warning $_.Exception.Message
}
}
}

Related

Move multiple users to multiple OUs importing users from CSV and filtering by Active Directory "Office" attribute using Wildcard lookups

I'm trying to move users from an onboarding CSV file to several different OUs after the account creation but I'm having issues with the syntax. Is it possible to use a wildcard lookup for a certain keyword such as "Remote" on the users Active Directory office attribute? Below is a snippet of the code.
$map = #{
'China' = "China OU DistinguishedName"
'Russia' = "Russia OU DistinguishedName"
'US - Miami' = "Miami OU DistinguishedName"
'US - Tampa' = "Tampa OU DistinguishedName"
'US - Reno' = "Reno OU DistinguishedName"
'US - Charleston' = "Charleston OU DistinguishedName"
}
foreach($line in Import-Csv "C:\Test\Test Files\AD_Test.csv") {
$firstname = $line.'Legal First Name'.Trim()
$preferred_firstname = $line.'Preferred First Name'.Trim()
if($preferred_firstname){
$firstname = $preferred_firstname
}
$lastname = $line.'Last Name'.Trim()
$displayname = $firstname + " " + $lastname
$param = #{
# create a filter for this user
# try to find him either by CommonName OR SamAccountName OR DisplayName
LDAPFilter = "(|(cn=$displayName)(samAccountName=$displayName)(displayName=$displayName))"
Properties = "Office"
}
# if the user can be found in AD
if($user = Get-ADUser #param) {
# if the user's Office cannot be found in `$map`
if(-not $map.ContainsKey($user.Office)) {
Write-Warning "Office for '$displayName' could not be determined, skipping."
# go to next line in Csv
continue
}
# if the user's Office can be found in `$map`, move it to the destination OU
$user | Move-ADObject -TargetPath $map[$user.Office]
# and after moving it, skip below logic, go next
continue
}
# if the user could not be found in AD
Write-Warning "'$displayName' could not be found in AD."
}
As explained in previous answer, the hash table should be used for exact lookups, however you can still use it, but you would need to add more conditions in case the value for Office of the users couldn't be found in $map. For this you can use a switch to evaluate multiple conditions.
To understand the use of the :outer label, see about_Continue.
$map = #{
# stays as-is, only exact values here
}
# set `outer` label for this loop
:outer foreach($line in Import-Csv "C:\AD_Test.csv") {
# `$displayname` and `$param` code stays as-is here
# if the user could not be found in AD
if(-not ($user = Get-ADUser #param)) {
# display the warning
Write-Warning "'$displayName' could not be found in AD."
# and skip next logic
continue
}
# if the user can be found in AD, switch on `$user.Office`
$destination = switch($user.Office) {
# if the value is found on `$map` hashtable
# get the destination OU, and break the switch loop
{ $map.ContainsKey($_) } { $map[$_]; break }
# if the value contains "Remote", output this OU and break the loop
{ $_ -like "*Remote*" } { 'OU=Remote Here,DC=DOMAIN,DC=com'; break }
# if above conditions were `$false`, the Default action is
# display the warning message and go to next line of Csv
Default {
Write-Warning "Office for '$displayName' could not be determined, skipping."
continue outer
}
}
# if we are here, we can assume `$destination` is populated
# hence we can move the user
$user | Move-ADObject -TargetPath $destination -WhatIf
}

Can someone help me with a powershell script that will add users to groups based Their OU?

I am trying to create a script to add people to groups and i would like something like an IF statement that will automatically add our employees to their VLAN group if they are in a certain OU. Lets say our employees are in OU = test and they will be added to the group "Test VLAN"
I would like to add this to my script that checks which OU they're in and adds them to a specific VLAN group.
Thanks
Here you go, no activedirectory module needed.
You would need to adjust the LDAP filter to your liking. Currently it does it for all user objects with the Title field populated
$VerbosePreference = "Continue"
[void][System.Reflection.Assembly]::LoadWithPartialName("System.DirectoryServices.AccountManagement")
# LDAP search filter, this gets all users with the title field populated
$searchFilter = "(&(objectclass=user)(title=*))"
# Hash mapping between group name and OU
$mapping = #(
[PSCustomObject]#{ Name = "Test VLAN"; Value = "OU=Test,OU=Users,DC=contoso,DC=com"}
[PSCustomObject]#{ Name = "Test VLAN 2"; Value = "OU=Test2,OU=Users,DC=contoso,DC=com"}
[PSCustomObject]#{ Name = "Test VLAN 123123"; Value = "OU=Test123123,OU=Users,DC=contoso,DC=com"}
)
# Get all users in Active Directory
$directorySearcher = New-Object System.DirectoryServices.DirectorySearcher([ADSI]"")
$directorySearcher.Filter = $searchFilter
$directorySearcher.PropertiesToLoad.Add("samaccountname")
$directorySearcher.PropertiesToLoad.Add("distinguishedname")
$users = $directorySearcher.FindAll()
$domainName = [System.DirectoryServices.ActiveDirectory.Domain]::GetCurrentDomain().Name
$principalContext = [System.DirectoryServices.AccountManagement.PrincipalContext]::new("Domain",$domainName)
# Loop through users and add them to group
foreach ($user in $users) {
$userPrincipal = [System.DirectoryServices.AccountManagement.UserPrincipal]::FindByIdentity($principalContext, $user.Properties.samaccountname)
if ($userPrincipal) {
$vlanGroup = $mapping.Where({$user.Properties.distinguishedname.EndsWith($_.Value)})
if ($vlanGroup) {
$groupPrincipal = [System.DirectoryServices.AccountManagement.GroupPrincipal]::FindByIdentity($principalContext, $vlanGroup.Name)
if ($userPrincipal.IsMemberOf($groupPrincipal)) {
Write-Verbose "User '$($user.Properties.samaccountname)' is already memberof '$($vlanGroup)'"
}
else {
$groupPrincipal.Members.Add($userPrincipal)
$groupPrincipal.Save()
Write-Verbose "Added user '$($user.Properties.samaccountname)' to group '$($vlanGroup)'"
}
}
else {
Write-Verbose "No VLAN mapping found for user '$($user.Properties.samaccountname)'"
}
}
else {
Write-Verbose "Unable to find userprincipal for '$($user.Properties.samaccountname)'"
}
Clear-Variable 'userPrincipal', 'vlanGroup', 'groupPrincipal' -ErrorAction SilentlyContinue
}

Powershell - Checking Security Group Members against another list

A bit of context, I am trying to get a list of users from a security group, then check if any of those users do not have an assigned XenDesktop.
Please forgive me, I only started using Powershell yesterday so my formatting is off. It first grabs the users from the AD group then checks if that user has an assigned desktop, which works but I what I can't seem to get working is that if the user is found in that list, I want it to move onto the next username, instead it continues to check against every machine and then onto the final bits of code.
$checkusernames = Get-ADGroupMember "***AD security Group***" | Select SamAccountName
$desktops = get-brokerdesktop -DesktopGroupName Personal_WIN8 | Select MachineName, #{Name='AssociatedUserNames';Expression={[string]::join(“;”, ($_.AssociatedUserNames))}}
foreach ($username in $checkusernames.SamAccountName) {
foreach ($desktop in $desktops) {
If ($desktop.AssociatedUserNames -like "*$username*") {
write-host $username "is assigned to" $desktop.machinename
}
write-host $username "is not assigned to a desktop"
}
Write-host $username "is not assigned to anything"
pause
}
If you want to exit from a ForEach loop early you can do so with the Break keyword. For example:
$checkusernames = Get-ADGroupMember "***AD security Group***" | Select SamAccountName
$desktops = get-brokerdesktop -DesktopGroupName Personal_WIN8 | Select MachineName, #{Name='AssociatedUserNames';Expression={[string]::join(“;”, ($_.AssociatedUserNames))}}
foreach ($username in $checkusernames.SamAccountName) {
$machine = ''
foreach ($desktop in $desktops) {
If ($desktop.AssociatedUserNames -like "*$username*") {
$machine = $desktop.machinename
break
}
}
If ($machine) {
write-host $username "is assigned to" $desktop.machinename
} Else {
write-host $username "is not assigned to a desktop"
pause
}
}
This will stop the current cycle of the inner ForEach loop (once it has completed in it's entirety) without interrupting the ongoing cycle of the outer one.
Per the dicussion in the comments, i've also reorganised the code so that you only get a single output dependent on whether a desktop is matched to a user or not and it only pauses if it does not find a match.

AD user creation with SamAccountName availability check loop

I'm learning Powershell by making a script that will hopefully automate everything that needs to be done when we get a new hire or a consultant. Currently I'm working on the part that will create the AD account. Below are the variables specific to this portion of the script.
#Variables for preliminary SamAccountName, modifiers and initials array
$PrelSamAccountName = ("se" + [string]$GivenName.Substring(0,3) + [string]$SurName.Substring(0,3)).ToLower()
$Modifier1 = 1
$Modifier2 = 0
$InitialsArray = #("x","y","z")
Here is the loop. I cut out a bunch of parameters on New-ADUser to make it less cluttered.
try {
#Checks if preliminary SamAccountName is taken or not
$ADCheck = Get-ADUser -Filter {SamAccountName -eq $PrelSamAccountName}
#Creates new user
New-ADUser -Name $Name -SamAccountName $PrelSamAccountName
} catch {
#Replaces final character in preliminary SamAccountName with "1++"
while (($ADCheck | Select-Object -ExpandProperty SamAccountName) -eq $PrelSamAccountName) {
$PrelSamAccountName = ([string]$PrelSamAccountName.Substring(0,7) + ($Modifier1++)).ToLower()
}
#Changes $Initials from $null to x/y/z if an existing user has identical name as new user
while (($ADCheck | Select-Object -ExpandProperty Name) -eq $Name) {
$Initials = $InitialsArray[$Modifier2++]
$Name = $GivenName + " " + $Initials + " " + $SurName
}
}
Everything is working as intended, except for the fact that a new user is created every other time I run the loop. Ideally I would want it to create a new user every time it is run. :)
I'm assuming it has something to do with the placement of the $ADCheck variable, but after having rewritten this portion multiple times I simply can't get it to work. Any ideas?
Thanks in advance.
You have some logical problems in here:
Follow this Approach:
Pseudocode:
while (user exist) {create new username}
new-aduser new username
PS Code:
function new-sam
{
#creates new sam
}
$sam = "username"
$a=$false
while (!$a)
{
try {
$a = [bool](Get-ADUser -Identity $sam )
}
catch {
$a = $false; $sam = new-sam
}
}
new-aduser ....

How to ensure the existence of user before deleting from local user group?

I am trying to Replace a user in local group using powershell script.
Function ReplaceUserInGroup {
Param (
[string]$Group,
[string]$OldUserName,
[string]$NewUserName
)
[string]$computer=$env:ComputerName
If($Group -And $OldUserName -And $NewUserName ) {
$LocalGroup = [ADSI]"WinNT://$computer/$Group,group"
$LocalGroup.Add("WinNT://$computer/$NewUserName")
$LocalGroup.Remove("WinNT://$OldUserName")
}
Else {
Write-Warning " ReplaceUserInGroup : Some or all the parameters are empty"
}
}
The problem with this script is ,it will fail if the OldUserName doesn't exist in the local group.
I would like to check whether the user exists in the group before removing the user from localgroup.
In other words I would like to wrap Remove function line in some if condition like belows.
If (UserName exists in Localgroup) {
$LocalGroup.Remove("WinNT://$OldUserName")
}
How to check the user existence?
$members = $LocalGroup.psbase.Invoke("Members") | Foreach-Object {$_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null) }
if($members -contains $OldUserName)
{
"$OldUserName is member"
}
else
{
"$OldUserName is NOT a member"
}
$objOu = [ADSI]"WinNT://${env:Computername}"
$localUsers = $objOu.Children | where {$_.SchemaClassName -eq 'user'} | % {$_.name[0].ToString()}
# Ensure we have local user BOB
if($localusers -contains "BOB" ){
Write-Host "local user ${env:Computername}/BOB already exists"
}
else{
Write-Host "Creating local user: /BOB"
NET USER BOB "qwefgnbm" /ADD
}
This checks if a user exists and adds one if it is not present. It may be of use.