Compare 2 ActiveDirectory properties using Powershell - powershell

My Goal is to List all ADusers where the property proxyAddresses does not contain the value from the mail property.
My first step is to get all users that have both values filled with:
$ADUser = Get-ADUser -Properties Name,Mail,proxyAddresses -Filter {proxyAddresses -like '*' -and mail -like '*'}
then i try to run it trough a foreach loop with an integrated if statement
$result = foreach ($User in $ADUser){
$proxystring = $User.proxyAddresses
$Mailstring = $User.Mail
$Mailstring = $Mailstring.ToString()
if ($proxystring -contains '*$Mailstring*'){
Write-Host 'läuft'
}
else{
Write-Output($User).Name
}
}
in the if statement i tried
if ($proxystring -contains '*$Mailstring*')
if ($proxystring -contains $Mailstring)
if ($proxystring -like $Mailstring)
if (($proxystring).contains($Mailstring))
As in the mainpart of the Code seen, I also tried to pass it to a string because i thought the format might be a problem.
Everywhere i looked a variable only gets matched with a string, not with other variables.
If anyone happens to know what my mistake is i would be grateful.

You would need to remove the preceding SMTP: / smtp: from each address in proxyAddresses for this to work properly:
$result = :outer foreach ($User in $ADUser){
foreach($address in $user.proxyAddresses) {
# remove the leading `smtp:` from each address
$mail = $address -replace '^smtp:'
# and compare, if the user's mail was in the `proxyAddresses` array
if($mail -eq $User.mail) {
# there is no need to keep checking, we can skip this user
# and go next
continue outer
}
}
# if the user's `mail` wasn't found in the `proxyAddresses` array
# output this user
$user
}
You could also use -notcontains to simplify the above code a lot but this requires prepending smtp: to user's mail attribute:
$result = foreach ($User in $ADUser){
if($user.proxyAddresses -notcontains ('smtp:' + $user.mail)) {
$User
}
}

Related

Use -like variable in powershell if statement

Is it possible to use -like and wildcard search in a PowerShell if statement - i'm trying to do something like this;
$name = 'matt'
$current = 'matt#'
if ($name -like "*$current*"){
write-host("this name matches")
}
However the "$current" does not work - please advise?
The other way around works...
$name = 'matt#'
$searchkey = 'matt'
if ($name -like "*$searchkey*"){
write-host("this name matches")
}

Check a username list and if they already exist Powershell

I have a CSV with 100 Usernames i have to check now if they already exist. Whats the best way to do that?
And is there a possibility that if the Username "marmar" is already used the programm checks by its own if username "marmar1" or if that is used aswell "marmar2" is free?
Is it easier to read the Usernames through the csv or should i copy them into Powershell?
examples of Usernames:
marmar
langas
ianmow
lowbob
berret
lawpaw1
etc.
Open for ideas and tipps.$
Thanks very much
If your CSV file looks anything like
"UserName","OtherStuff"
"marmar","blah"
"langas2","blahblah"
"ianmow","blahblahblah"
"lowbob","blahblahblahblah"
"berret","blahblahblahblahblah"
"lawpaw1","blahblahblahblahblahblah"
You can do that with something like this:
$freeUserNames = Import-csv 'D:\UsersNamesToCheck.csv' | ForEach-Object {
#Check to see if the user already exists in AD
$name = $_.UserName
$dupes = Get-ADUser -Filter "SamAccountName -like '$name*'" -ErrorAction SilentlyContinue | Select-Object -ExpandProperty SamAccountName
$index = 1
# check if the username is already in use and if so, increase the index number and test again
while ($dupes -contains $name) {
$name = '{0}{1}' -f ($name -replace '\d+$'), $index++
}
$name
}
# output on screen
Write-Host "Unused usernames:`r`n"
$freeUserNames
Possible output:
Unused usernames:
marmar
langas1
ianmow1
lowbob
berret1
lawpaw2

Struggling with If Statements

I have problems of understanding values of variables in PowerShell and I check them with if statements.
$LDAPDirectoryService = '10.10.XXX.XXX:389'
$DomainDN = 'o=Enterprise'
#$LDAPFilter = '(&(objectCategory=Person)(memberOf=cn=alc-01-Planung-rw,ou=KT,o=enterprise))'
$LDAPFilter = '(&(cn=alc-01-Planung-rw))'
$null = [System.Reflection.Assembly]::LoadWithPartialName('System.Net')
$LDAPServer = New-Object System.DirectoryServices.Protocols.LdapConnection $LDAPDirectoryService
$LDAPServer.AuthType = [System.DirectoryServices.Protocols.AuthType]::Anonymous
$Scope = [System.DirectoryServices.Protocols.SearchScope]::Subtree
$AttributeList = #('*')
$SearchRequest = New-Object System.DirectoryServices.Protocols.SearchRequest -ArgumentList $DomainDN,$LDAPFilter,$Scope,$AttributeList
$groups = $LDAPServer.SendRequest($SearchRequest)
$groups
if ($groups -eq $null) {"No Group found"}
if ($groups -eq " ") {"No Group found"}
foreach ($group in $groups.Entries) {
$users = $group.attributes['member'].GetValues('string')
foreach ($user in $users) {
Write-Host $user
}
}
I want to check if the group exists and then if users are existing in this group. I tried many statements but none of them seem to work.
It's not null or blank, even when nothing is written down in the console.
This is what I got when I use group which doesn't exist:
Can anybody show me a solution?
What version of PowerShell are you running? Why are you not using the built-in AD group cmdlets for this or are you not using ADDS but some other LDAP service?
Or you may be on OSX/Linux and are using PSCore, which the ADDS/RSAT cmdlets are not there, well, not yet?
For your goals of …
I want to check if the group exists and then if users are existing in
this group.
… On Windows, with PowerShell 3x or higher, it's really only this...
# Get all AD groups and all members of each group
Clear-Host
(Get-ADGroup -Filter '*').Name |
%{
"`n*** The members of $PSItem are as follows: ***`n"
If((Get-ADGroupMember -Identity $PSItem).Count -ge 1)
{
(Get-ADGroupMember -Identity $PSItem).SamAccountName
}
Else
{
Write-Warning -Message "$PSItem does not exist or has no members."
}
}
# Filtered
Clear-Host
((Get-ADGroup -Filter '*').Name -match 'Domain Admins|Domain Users' ) |
%{
"`n*** The members of $PSItem are as follows: ***`n"
If((Get-ADGroupMember -Identity $PSItem).Count -ge 1)
{
(Get-ADGroupMember -Identity $PSItem).SamAccountName
}
Else
{
Write-Warning -Message "$PSItem does not exist or has no members."
}
}
Using your LDAP approach though... How about this...
'Administrators','Distributed COM Users' |
ForEach {
# Define LDAP search root, the Global catalog of the domain
$sLDAPSearchRoot = "LDAP://$((Get-ADDomainController).IPv4Address):389"
# The Groupname to looking for
($sGroupName = "$_")
# The LDAP query - query string
$sSearchStr = "(&(objectCategory=group)(name="+$sGroupName+"))"
# Get the search object
$oSearch = New-Object directoryservices.DirectorySearcher($oADRoot,$sSearchStr)
# Looking for the group
$oFindResult = $oSearch.FindAll()
# On success, get a DirectoryEntry object for the group
$oGroup = New-Object System.DirectoryServices.DirectoryEntry($oFindResult.Path)
# And list all members
If (($oGroup.Member).Count -ge 1)
{
$oGroup.Member |
%{($oMembers = New-Object System.DirectoryServices.DirectoryEntry($sLDAPSearchRoot+"/"+$_))}
}
Else
{ Write-Warning -Message "$($oGroup.Member) does not exist or has no members"}
}

WMI pulls current user even if never logged in

I am new to powershell, and I am attempting to create a CSV from an excel file for comparison sake to see who is currently logged into a computer. However, I'm running into an odd issue where sometimes the script will pull the same user multiple times even if they've never logged into a computer. Here is my full code. I know there is a lot of optimization that can be done (and parts that need to be removed, those should be noted). I assume I've misused Get-WMIObject or something similar, can anyone see why it would pull that information like it is?
$csvRunFile = "test.csv"
$output = "Results_$(Get-Date -format yyyy.MM.dd).csv"
#Import the created csv.
$csv = import-csv $CsvRunFile
$results = foreach($csv_line in $csv) {
$ctag = $csv_line.ctag
$test_ping = test-connection $ctag -Count 1 -Quiet
#If the computer is pingable (IE: Online)
switch ($test_ping) {
$true {
#Pull the actual logged in user.
$Username = (Get-WmiObject -ComputerName $ctag -Class Win32_ComputerSystem).Username.Split("\\")[1]
#If the last modified folder is 'public' put an error, otherwise pull the username's information from AD.
#This was from when it pulled from the \User folder rather than the last log in, this is probably removeable.
if ($Username -eq "Public") {
$ADName = "No User"
} else {
$ADName = Get-ADUser -Identity $Username
$ADName = $ADName.Name
} #end If
}#end Switch:True
#Show there was an error when pinging the computer.
$false {$ADName = "ERROR"}
}#end Switch
#write the results the new output CSV.
$result = [PSCustomObject]#{
CTAG = $ctag
Username = $ADName
}#end PSCustom Object
$result
} #end foreach
#Turn the .txt into a CSV so it can be manually compared to the list in the original excel file.
$results | Export-Csv -path $output
There might be a leftover-value in $UserName for some reason or $ADName is still it's old value because you tried to run Get-ADUser -Identity $null when there was no user logged on (WMI returns $null when there's no user logged in).
I also changed your ping-test from a switch to an if-test just to cleanup the code. I've never seen Public being returned, but I left it as it doesn't really hurt either.
Try:
#If the computer is pingable (IE: Online)
if($test_ping) {
#Clear username var just to be safe
$Username = $null
#Pull the actual logged in user.
$Username = (Get-WmiObject -ComputerName $ctag -Class Win32_ComputerSystem).Username | ? { $_ } | % { $_.Split("\\")[1] }
#If the last modified folder is 'public' put an error, otherwise pull the username's information from AD.
#This was from when it pulled from the \User folder rather than the last log in, this is probably removeable.
if (($Username -eq "Public") -or ($Username -eq $null)) {
$ADName = "No User"
} else {
$ADName = Get-ADUser -Identity $Username
$ADName = $ADName.Name
} #end If username public
} else { $ADName = "ERROR"}

Multiple variables in Foreach loop [PowerShell]

Is it possible to pull two variables into a Foreach loop?
The following is coded for the PowerShell ASP. The syntax is incorrect on my Foreach loop, but you should be able to decipher the logic I'm attempting to make.
$list = Get-QADUser $userid -includeAllProperties | Select-Object -expandproperty name
$userList = Get-QADUser $userid -includeAllProperties | Select-Object -expandproperty LogonName
if ($list.Count -ge 2)
{
Write-host "Please select the appropriate user.<br>"
Foreach ($a in $list & $b in $userList)
{
Write-host "<a href=default.ps1x?UserID=$b&domain=$domain>$b - $a</a><br>"}
}
}
Christian's answer is what you should do in your situation. There is no need to get the two lists. Remember one thing in PowerShell - operate with the objects till the last step. Don't try to get their properties, etc. until the point where you actually use them.
But, for the general case, when you do have two lists and want to have a Foreach over the two:
You can either do what the Foreach does yourself:
$a = 1, 2, 3
$b = "one", "two", "three"
$ae = $a.getenumerator()
$be = $b.getenumerator()
while ($ae.MoveNext() -and $be.MoveNext()) {
Write-Host $ae.current $be.current
}
Or use a normal for loop with $a.length, etc.
Try like the following. You don't need two variables at all:
$list = Get-QADUser $userid -includeAllProperties
if ($list.Count -ge 2)
{
Write-Host "Please select the appropriate user.<br>"
Foreach ($a in $list)
{
Write-Host "<a href=default.ps1x?UserID=$a.LogonName&domain=$domain>$a.logonname - $a.name</a><br>"
}
}