Powershell won't find equal for $var in csv file - powershell

I'm pretty new to powershell and I'm trying to assign Exchange-groups and shared mailboxes with an Powershell script. I have a .csv file with the job title, department and all the associated groups and mailboxes. I wrote the following script to achieve my goal but it doesn't work.
I have the feeling that the Where {$_.JobTitle -eq $JOBcsv -and $_.Department -eq $DEPcsv} part is making the script fail. If I put a text value like 'Accountmanager' instead of $JOBcsv all works fine. Thanks in advance!
Connect-ExchangeOnline -Credential $cred
Connect-AzureAD -Credential $cred
$User=Read-Host -Prompt 'Write UPN'
$DEPcsv=Get-AzureADUser -ObjectId $User | Select Department
$JOBcsv=Get-AzureADUser -ObjectId $User | Select JobTitle
$Groups = Import-CSV -Path "C:\PS Scripts\Groepen en Mailboxen.csv" -Delimiter ";" | Where {$_.JobTitle -eq $JOBcsv -and $_.Department -eq $DEPcsv} | Select Groepen
ForEach ($item in $Groups)
{Add-DistributiongroupMember $item -Member $User}
$Mailboxes = Import-CSV -Path "C:\PS Scripts\Groepen en Mailboxen.csv" -Delimiter ";" | Where {$_.JobTitle -eq $JOBcsv -and $_.Department -eq $DEPcsv} | Select Mailboxen
ForEach ($item in $Mailboxes)
{Add-MailboxPermission $item -user $User -AccessRights FullAccess -InheritanceType All}

Related

Matching security group names based on $variable.name

Ok so I'm trying to automate the creation of security groups under a specific OU. The keystone is group membership, so basically If member of group A -> create group B.
So I'm filling a variable with the name attribute of an "All Managers" group. Then I want to loop through those $names and check for the existence of another group using {Name -like 'Reports to $name'}
The looping part is throwing me off, here's what I've got:
import-module activedirectory
$ou = "ou=Stuff, ou=Resources, ou=Groups, ou=Org, dc=domain, dc=net"
$creds = "domain.net\user"
$server = "<domain controller>"
$managers = get-adGroupMember -server $server -Credential $creds -identity "All Managers" | select name
$name = $managers.name
$ReportsTo = Get-adgroup -server $server -credential $creds -searchbase $ou -filter "Name -like 'Reports to *'" | where {$_.name -replace 'Reports to ' -in $name} | select name
$Reports = $reportsto.name
$reports
ForEach ($manager in $managers){
If ($ReportsTo -NotContains $name)
#{$name}
{New-ADGroup -name "Reports to "$name -groupscope Global -path $ou}
}
it's ugly I know, but like i said I'm not sure how to process the loop, they are still new to me.
You may do the following:
$ou = 'ou=Stuff,ou=Resources,ou=Groups,ou=Org,dc=domain,dc=net'
$creds = "domain.net\user"
$server = "<domain controller>"
# Get Manager names only
$managers = Get-ADGroupMember -Server $server -Credential $creds -Identity 'All Managers' |
Select-Object -ExpandProperty Name
# Get Group names that are in the format Reports to Manager Name
$ReportsTo = Get-ADGroup -Server $server -Credential $creds -SearchBase $ou -Filter "Name -like 'Reports to *'" |
where {$_.Name -replace 'Reports to ' -in $managers} |
Select-Object -ExpandProperty Name
# Find manager names that don't have a Reports to group
Compare-Object $managers ($ReportsTo -replace 'Reports to ') -PassThru | Foreach-Object {
# Pipe found manager names into New-ADGroup command's -Name parameter
New-ADGroup -Name "Reports to $_" -GroupScope Global -Path $ou -Server $server -Credential $creds
}
Compare-Object by default only lists differences.

How to Output to a Log File

How can I output the screen results to a txt file when I run this code?
#removes disabled clinical or corp accounts from SGs in the I-Drive OU
$searchOU = "OU=I-Drive,OU=SAS,OU=Application Security Groups,OU=Groups,OU=Enterprise,DC=z,DC=x,DC=y"
Get-ADGroup -Filter 'GroupCategory -eq "Security"' -SearchBase $searchOU | ForEach-Object{ $group = $_
Get-ADGroupMember -Identity $group | Get-ADUser | Where-Object {$_.Enabled -eq $false} | ForEach-Object{ $user = $_
$uname = $user.Name
$gname = $group.Name
Write-Host "Removing $uname from $gname" -Foreground Yellow
Remove-ADGroupMember -Identity $group -Member $user -Confirm:$false
}
}
Pipe the output of Get-ADGroup to Set-Content like so:
Get-ADGroup -Filter 'GroupCategory -eq "Security"' -SearchBase $searchOU | ForEach-Object{
$group = $_
Get-ADGroupMember -Identity $group | Get-ADUser | Where-Object { $_.Enabled -eq $false} | ForEach-Object{
$user = $_
$uname = $user.Name
$gname = $group.Name
Write-Host "Removing $uname from $gname" -Foreground Yellow
Remove-ADGroupMember -Identity $group -Member $user -Confirm:$false
}
} | Set-Content filename.txt
If you want any additional output (warnings, verbose, errors) change the last line a bit to redirect the other streams:
} *>&1 | Set-Content filename.txt
Alternatively, you can also use the built-in transcript logging to log everything to a file as well just call one of the following from within your script:
Start-Transcript
or if you want the log to go to a specific place:
Start-Transcript -Path "\Path\To\LogFile.log"
Note that transcript logging is more useful in scripts than during an interactive session.
Store the value you'd like to log in a variable say $abc
Write to log file and keep appending $abc | Out-File -FilePath "C:\Somewhere\log.txt" -Append -Encoding UTF8
Refer - Log output of ForEach loop

Add domain to excel name

I'm currently connecting to a domain controller that is on a different domain. I'm trying to automate a report that tells us if a user is enabled and the last time they logged in. I'm looking to either add the domain name to the excel output or even rename the tabs inside the workbook. Currently I just name the excel sheet by the IP of the domain controller. I have a total of 8 domains Thank you for any help.
$domainserver = "ipaddress1" , "ipaddress2" , "ipaddress3"
foreach ($s in $domainserver){
Get-ADUser -Credential $Credential -Server $s -Filter {Enabled -eq $TRUE} -Properties Name,SamAccountName,LastLogonDate |
Where {($_.LastLogonDate -lt (Get-Date).AddDays(-30)) -and ($_.LastLogonDate -ne $NULL)} |
Select Name,SamAccountName,LastLogonDate | Sort-Object LastLogonDate |
Export-Csv C:\temp\$s.csv -NoTypeInformation
}
Run Get-AdDomain against the same server, to find domain details:
$domainserver = "ipaddress1" , "ipaddress2" , "ipaddress3"
foreach ($s in $domainserver)
{
$domain = Get-AdDomain -Server $s -Credential $Credential
Get-ADUser -Credential $Credential -Server $s -Filter {Enabled -eq $TRUE} -Properties Name,SamAccountName,LastLogonDate |
Where {($_.LastLogonDate -lt (Get-Date).AddDays(-30)) -and ($_.LastLogonDate -ne $NULL)} |
Select-Object -Property Name,SamAccountName,LastLogonDate,#{Label='Domain'; Expression={$domain.DnsRoot}} |
Sort-Object LastLogonDate |
Export-Csv C:\temp\$s.csv -NoTypeInformation
}

bulk creation of forwarding addresses and contacts via powershell

I am trying to move mailboxes to a new Exchange server on a different O365 tenant. This script is a portion of this move which attempts to list all Exchange Online users who have licenses, create a contact for each user pointing to their new email address, and forwards their email to their new address as well as their mailbox
#requires -Version 3 -Modules MSOnline
$mailboxlist = Get-Mailbox | Select-Object -Property userprincipalname |
Get-MsolUser | Where-Object -Property islicensed -EQ -Value $true |
Select-Object -Property firstname, lastname, userprincipalname |
Where-Object -Property firstname -NE -Value $null |
Format-list -AutoSize
#Begin foreach loop
foreach ($item in $mailboxlist)
{
#Create the forwarding address
$forwardingaddress = $item.firstname + '.' + $item.lastname + '#newdomain.com'
#Check for a contact, add if not present
If (!(Get-MailContact $forwardingaddress -ErrorAction silentlycontinue)){
New-MailContact $forwardingaddress -ExternalEmailAddress $forwardingaddress
}
#assign forwarding address
set-mailbox -ForwardingAddress $forwardingaddress -DeliverToMailboxAndForward $true
}
The result of the above is a $mailboxlist which is populated with first and last names and the users UPN which is also an email address. The result of $forwardingaddress is .#newdomain.com.
I don't think I am creating the initial data correctly for the foreach loop. I know that if I replace the $item.firstname with $_.firstname I get the same empty result. I would much appreciate if someone knowledgeable on the topic could assist.
Thanks!
Edit: Final config with Kiran's suggestion
#requires -Version 3 -Modules MSOnline
$mailboxlist = Get-Mailbox | Get-MsolUser | Where-Object { ($_.islicensed -eq $true) -and ($_.firstname -ne $null) }
#Begin foreach loop
foreach ($item in $mailboxlist)
{
#Create the forwarding address
$forwardingaddress = $item.firstname + '.' + $item.lastname + '#newdomain.com'
#Remove any spaces from the email address
$forwardingaddress = ($forwardingaddress -replace " ","").trim()
#Check for a contact, add if not present
If (!(Get-MailContact $forwardingaddress -ErrorAction silentlycontinue))
{
New-MailContact $forwardingaddress -ExternalEmailAddress $forwardingaddress
}
#assign forwarding address
Set-Mailbox -ForwardingAddress $forwardingaddress -DeliverToMailboxAndForward $true
}
try this:
$mailboxlist = Get-Mailbox | Get-MsolUser |
Where-Object { ($_.islicensed -eq $true) -and ($_.firstname -ne $null) }
the UserPrincipalName of get-Msoluser accepts pipeline input by propertyname so you should just pipe the output of get-mailbox to get-msoluser
select-object should be preferred over format-* commands because of the type of objects that are created.
Use format* when you want to show data on the console.
The where-object clause allows you to create complex conditions so try to combine them where you can. This should be the flow of commands:
cmdlet | where-object { some condition(s)} | select properties

Get recursive group membership of all AD users using Powershell

I'm trying to make a PS script which would list all Active Directory user group membership (recursive).
I already have working script:
import-module activedirectory
$users = get-aduser -Filter {Name -Like "*"} -Searchbase "ou=Users, dc=Domain" | Where-Object { $_.Enabled -eq 'True' }
$targetFile = "D:\users.csv"
rm $targetFile
Add-Content $targetFile "User;Group"
foreach ($user in $users)
{
$groups = Get-ADPrincipalGroupMembership $user
foreach ($group in $groups)
{
$username = $user.samaccountname
$groupname = $group.name
$line = "$username;$groupname"
Add-Content $targetFile $line
}
}
But script doesn't list groups recursively, i.e., if group listed in the output file is part of another group.
Example:
Group1: User
Group2: Group3: User
Script shows only Group1 and 3 but not 2.
What should I add to the first script that it writes group membership recursively?
Sorry I am publishing an answer for a question from 3 years ago but if someone will see it, it can help.
Credit to:
How to get ALL AD user groups (recursively) with Powershell or other tools?
You can use the LDAP_MATCHING_RULE_IN_CHAIN:
Get-ADGroup -LDAPFilter "(member:1.2.840.113556.1.4.1941:=CN=User,CN=USers,DC=x)"
You can use it anywahere that you can use an LDAP filter.
Example:
$username = 'myUsername'
$dn = (Get-ADUser $username).DistinguishedName
Get-ADGroup -LDAPFilter ("(member:1.2.840.113556.1.4.1941:={0})" -f $dn) | select -expand Name | sort Name
Fix in your script:
import-module activedirectory
$users = get-aduser -Filter {Name -Like "*"} -Searchbase "ou=Users, dc=Domain" | Where-Object { $_.Enabled -eq 'True' }
$targetFile = "D:\users.csv"
rm $targetFile
Add-Content $targetFile "User;Group"
foreach ($user in $users)
{
$dn = $user.DistinguishedName
$groups = Get-ADGroup -LDAPFilter ("(member:1.2.840.113556.1.4.1941:={0})" -f $dn) | select -expand Name | sort Name
foreach ($group in $groups)
{
$username = $user.samaccountname
$groupname = $group.name
$line = "$username;$groupname"
Add-Content $targetFile $line
}
}
If you make it a function you can call it recursively. Check this out, I think you'll be pleased with the results:
Function Get-ADGroupsRecursive{
Param([String[]]$Groups)
Begin{
$Results = #()
}
Process{
ForEach($Group in $Groups){
$Results+=$Group
ForEach($Object in (Get-ADGroupMember $Group|?{$_.objectClass -eq "Group"})){
$Results += Get-ADGroupsRecursive $Object
}
}
}
End{
$Results | Select -Unique
}
}
Toss that at the top of your script, and then call it for each user. Something like:
import-module activedirectory
$users = get-aduser -Filter {Name -Like "*"} -Searchbase "ou=Users, dc=Domain" -Properties MemberOf | Where-Object { $_.Enabled -eq 'True' }
$targetFile = "D:\users.csv"
rm $targetFile
Add-Content $targetFile "User;Group"
foreach ($user in $users)
{
$Groups = $User.MemberOf
$Groups += $Groups | %{Get-ADGroupsRecursive $_}
$Groups | %{New-Object PSObject -Property #{User=$User;Group=$_}}|Export-CSV $targetfile -notype -append
}
Now, depending on the size of your AD structure that may take quite a while, but it will get you what you were looking for.
It is very easy. Just use ActiveRoles Management Shell for Active Directory. Cmdlet Get-QADMemberOf with parameter Indirect is the one you are looking for. Example:
Get-QADMemberOf john.smith -Indirect
The Quest object returned already include All Recursive groupes (and first level users) in properties $_.AllMembers
Add-PSSnapin Quest.ActiveRoles.ADManagement
$UsersFirstLevel = ($Members | Get-QADObject -Type Group -DontUseDefaultIncludedProperties | Get-QADGroupMember -DontUseDefaultIncludedProperties | ?{$_.type -eq 'user'})
$UsersSubGroup = ($Members | Get-QADObject -Type Group -DontUseDefaultIncludedProperties | Get-QADGroupMember -DontUseDefaultIncludedProperties | ?{$_.type -eq 'group'}).Allmembers | Get-QADObject -DontUseDefaultIncludedProperties | ?{$_.type -eq 'user'}
$RecursiveUsers = $UsersFirstLevel
$RecursiveUsers += $UsersSubGroup
$RecursiveUsers = $RecursiveUsers | Sort-Object -Unique
Newer versions of PowerShell (AD Module) do have -Recursive switch. So you can easily use Get-ADGroupMember.
Example: Get-ADGroupMember -Identity My_Group -Recursive