How to use the "-notcontains" conditional parameter when querying a BlockedSendersAndDomains list in PowerShell? - powershell

I am trying to make a list of all mailboxes who DO NOT have "conostco.com" domain on their BlockedSendersAndDomains list.
by using
$test= Get-MailboxJunkemailconfiguration -Identity * | fl Displayname, BlockedSendersAndDomains
I can get a list of all the names and the Blocked domains/email addresses associated to those names but for my purpose I want to get a list of all of the names of the mailboxes that DO NOT contain the domain "conostco.com". Is there such way to do it?

Based on the sample data you have given I am "assuming" BlockSendersAndDomains is an array.
So maybe you could do something like this then
$test= Get-MailboxJunkemailconfiguration -Identity * | % { $domains = $_.BlockedSendersAndDomains.GetEnumerator() | ? {$_ -notmatch 'conostco.com'}; $name = $_.displayname ; new-object PSObject -Property #{name=$displayname;domains=$domains} }
Again, there is no way for me to test, so see if that gives you a $test object collection which you can then re-use or just display, if you like.

Get-MailboxJunkEmailConfiguration -Identity * |
Where-Object {$_.BlockedSendersAndDomains -notlike '*conostco.com*' }

Related

Powershell - How to remove trailing spaces from a list of groups a user is in

I've copied/created a script to get all the members of a group that a user is part of, including nested groups. However, my output isn't quite the way I want it.
It goes in one of two ways. Either it outputs as one big string, which looks nice, but has trailing spaces on each line so I cannot simply copy and paste it into AD. Or if I change the Out-String to use -stream, it comes out as a garbled mess, but may allow me to trim the spaces.
I currently have the output going into a TextBox in a simple GUI.
Function Get-ADUserNestedGroups {
Param
(
[string]$DistinguishedName,
[array]$Groups = #()
)
#Get the AD object, and get group membership.
$ADObject = Get-ADObject -Filter "DistinguishedName -eq '$DistinguishedName'" -Properties memberOf, DistinguishedName;
#If object exists.
If($ADObject)
{
#Enummurate through each of the groups.
Foreach($GroupDistinguishedName in $ADObject.memberOf)
{
#Get member of groups from the enummerated group.
$CurrentGroup = Get-ADObject -Filter "DistinguishedName -eq '$GroupDistinguishedName'" -Properties memberOf, DistinguishedName;
#Check if the group is already in the array.
If(($Groups | Where-Object {$_.DistinguishedName -eq $GroupDistinguishedName}).Count -eq 0)
{
#Add group to array.
$Groups += $CurrentGroup;
#Get recursive groups.
$Groups = Get-ADUserNestedGroups -DistinguishedName $GroupDistinguishedName -Groups $Groups;
}
}
}
#Return groups.
Return $Groups;
}
Function Display-UserGroups {
#Get all groups.
$Groups = Get-ADUserNestedGroups -DistinguishedName (Get-ADUser -Identity $userSAM).DistinguishedName;
$ResultsTextBox.Text = $Groups | Select-Object Name| Sort-Object name | Out-String
The output with the first way looks like:
Group Name1(Eight Spaces Here)
Group Name2(Eight Spaces Here)
The output with the second way looks like:
Group Name1GroupName2GroupName3
Thanks for your help!
You need to trim your output, which can easily be done with String.Trim method. However, it can only be applied against strings. $Groups will be an array of ADObject types. You will need to return the Name values of those objects and apply the Trim() method to the values.
($Groups | Select -Expand Name | Sort).Trim() -join "`r`n"
You can use $Groups += $CurrentGroup.trimEnd() to add the value with the trailing spaces trimmed.
A few other methods you might want to research
.trim() # Trim leading and trailing
.trimEnd() # Trim trailing
.trimStart() # Trim leading
The padding is being caused by PowerShell's formatting system. Select-Object is returning single property (Name) objects. PowerShell outputs that as a table, which may have some padding. Out-String is keeping that padding which is why it was reflecting in your final output...
The name property of the group is already a string. There's no need to use Out-String if you unroll the Name property from your $Groups variable/collection.
With some other adjustments for readability & testing. Below will emit a single string with each group on a new line. That should be paste-able into AD, by which I think you meant Active Directory User & Computers.
Function Get-ADUserNestedGroups
{
Param
(
[string]$DistinguishedName,
[array]$Groups = #()
)
# Get the AD object, and get group membership.
$ADObject = Get-ADObject $DistinguishedName -Properties memberOf, DistinguishedName
# If object exists.
If( $ADObject )
{
# Enummurate through each of the groups.
Foreach( $GroupDistinguishedName in $ADObject.memberOf )
{
# Get member of groups from the enummerated group.
$CurrentGroup = Get-ADObject $GroupDistinguishedName -Properties memberOf, DistinguishedName
# Check if the group is already in the array.
If( $Groups.DistinguishedName -notcontains $GroupDistinguishedName )
{
# Add group to array.
$Groups += $CurrentGroup
# Get recursive groups.
$Groups = Get-ADUserNestedGroups -DistinguishedName $GroupDistinguishedName -Groups $Groups
}
}
}
# Return groups.
Return $Groups
}
$userSAM = 'UserName'
# Get all groups.
$Groups = Get-ADUserNestedGroups -DistinguishedName (Get-ADUser -Identity $userSAM).DistinguishedName
($Groups.Name | Sort-Object) -join [System.Environment]::NewLine
Among the secondary changes you'll see I removed the -Filter parameter in a few places. The DistinguishedName can be used as the -Identity parameter so no need to filter.
Also, where you were checking if the $Groups collection already had the current group I used the -notContains operator instead. That should be faster then repeatedly iterating the collection with |Where{...} The code is also shorter and more readable.
Note: if we reverse the operands we could use -notin which may look
nicer still
An aside; You should avoid appending arrays with +=. Doing so can causes performance problems because it creates a new array any copies the contents over. The best way to deal with this is to allow PowerShell to accumulate the results for you. If you must do the append directly, look into using Array Lists. There's a lot information on this, just google it.

displaying information from two objects in powershell

I'd like to display information from skype and from AD next to eachother. (I'm asking this as a specific question, but I've stumbled against this more often).
the simplified version would be this:
get-csuser | ForEach-Object { $_.displayname,(Get-ADUser -Identity $_.samaccountname -Properties officephone).officephone } | ft
This would show me the displayname from skype and the phone number from AD. But it will show it as new rows, while I would like to have it in one handy table.
What's the best way to achieve this?
Thank you
I think you are looking for "calculated properties" in Select-Object. name is your label and expression is a script-block. Both are wrapped in a hash-table.
#{ Name = ''; Expression = {}}
So, for your code, it can be like this(didn't check for syntax) :
get-csuser | ForEach-Object { $_.displayname, #{ n= 'officePhone'; e = { (Get-ADUser -Identity $_.samaccountname -Properties officephone).officephone } }
Note : we can use short-hands for name and expression.
Link : Further Examples
Maybe this helps you.
$list = foreach ($process in (Get-Process)) {
[PSCustomObject]#{
ProcessID = $process.Id
Name = $process.Name
}
}
$list | Format-Table
Of course, you adjust the loop for the objects you enter the information you want to get, but generally this may help.

Listing group membership combinations

Hoping i can get some help in my thinking here because im struggling to accomplish what im after and im doubting its even the best way to achieve this now!
Essentially i have a powershell script (see below) which successfully lists members of a certain filter i put in. This all works smoothly and outputs a list into a CSV.
The next part however is telling it to return only members who are members of specific group combo's. For example, a user might be a member of Group 1, Group 2 and Group 7 (lets say out of 9 groups with that naming scheme)
so im trying to return results of members who only match the statement that they are in TWO groups (Group 1 and Group 2) and exclude those who may only be in Group 1 but not Group 2....hope that makes sense.
# first im narowing down group search to all groups starting with Group and then a number (this is an example). This will return 9 groups. Group 1 through to Group 9
$Groups = (Get-AdGroup -filter * | Where-object { $_.name -like "Group *" } | select-object name -expandproperty name)
# Just standard Array
$Array = #()
$Data = [ordered]#{}
# so now im wanting to search for members in each of those groups we narrowed down to above
Foreach ($Group in $Groups) {
# This bit defines my search criteria. It works perfectly if i just return all users. But if i only want to display members that are in Group 1 AND Group 2....it does not return any results.
$Members = Get-ADGroupMember -identity $Group | Where-Object { ($Group.name -like "Group 1") -and ($Group.name -like "Group 2") } | Get-ADUser -Properties * | select-object givenName, sn, sAMAccountName, mail
# Eventually that will be displayed in the object below...this bit works fine
foreach ($Member in $Members) {
$Data."update" = "modify"
$Data."region" = $Group
$Data."login" = $Member.mail
$Data."first_name" = $Member.givenName
$Data."last_name" = $Member.sn
$Data."approver_level" = "BlankForNow"
#
$DataPSObject = New-Object PSObject -property $Data
#
$Array += $DataPSObject
}
}
#
$Array | Sort-Object -Property login | Export-Csv "D:\Temp\Groups.csv" -NoTypeInformation
Any ideas where i could be going wrong? Maybe its better to edit the outputted CSV and match statements that way. So remove lines from CSV where users are not a member of both? Not even sure if thats entirely possible with Import-CSV tbh
Thanks in advance!
If you want the common members of the groups "Operations" and "ServiceDeskLevel2"
# Get groups members
$membersGroup1 = Get-ADGroupMember "Operations"
$membersGroup2 = Get-ADGroupMember "ServiceDeskLevel2"
# Compares both groups and put common members in the $res list
$res = Compare-Object $membersGroup1 $membersGroup2 -PassThru -IncludeEqual -ExcludeDifferent
# Output the name of the common members from $res
$res | Format-List -Property name

Multiple rows in a grid [duplicate]

This question already has answers here:
Export hashtable to CSV with the key as the column heading
(2 answers)
Closed 4 years ago.
I'm trying to list all ad group memberships of specific users. The input would be a string of logins split with a comma 'login1,login2'.
So I go over each user and list their memberships with the username as title. Somehow it only shows the first entry. Also it shows the user groups in one row and I don't know how to change that.
Code below:
$users = $logon -split ','
$q = #()
foreach ($user in $users) {
$usernm = Get-ADUser -Filter 'samAccountName -like $user' | select Name
$useraccess = Get-ADPrincipalGroupMembership $user | Select-Object Name
$userobj = New-Object PSObject
$userobj | Add-Member Noteproperty $usernm.Name $useraccess.Name
$q += $userobj
}
Expected output would be something like:
fullnameuser1 fullnameuser2 list of users goes on...
------------- ------------- ------------------------
adgroup1 adgroup3 ...
adgroup2 adgroup4
... ...
In principle this would also mean that if i typed $q.'fullnameuser1' output would be:
fullnameuser1
-------------
adgroup1
adgroup2
...
Whenever the code is ran, it will only ever add the first user's access, also returning all groups on one row. So somehow I need to go over all the group memberships and add a row for each one.
First and foremost, PowerShell does not expand variables in single-quoted strings. Because of that Get-ADUser will never find a match unless you have a user with the literal account name $user. Also, using the -like operator without wildcards produces the same results as the -eq operator. If you're looking for an exact match use the latter. You probably also need to add nested quotes.
Get-ADUser -Filter "samAccountName -eq '${user}'"
Correction: Get-ADUser seems to resolve variables in filter strings by itself. I verified and the statement
Get-ADUser -Filter 'samAccountName -eq $user'
does indeed return the user object for $user despite the string being in single quotes.
If you want a fuzzy match it's better to use ambiguous name resolution.
Get-ADUser -LDAPFilter "(anr=${user})"
You may also want to avoid appending to an array in a loop, and adding members to custom objects after creation. Both are slow operations. Collect the loop output in a variable, and specify the object properties directly upon object creation.
$q = foreach ($user in $users) {
...
New-Object -Type PSObject -Property {
$usernm.Name = $useraccess.Name
}
}
Lastly, I'd consider using the user's name as the property name bad design. That would be okay if you were building a hashtable (which is mapping unique keys to values), but for custom objects the property names should be identical for all objects of the same variety.
New-Object -Type PSObject -Property {
Name = $usernm.Name
Group = $useraccess.Name
}
Basily query all the users and store it in $users, example:
Get-ADUser -Filter * -SearchBase "dc=domain,dc=local"
And then you can export the results as csv or a table.
To Export as CSV :
Get-ADPrincipalGroupMembership <Username> | select name, groupcategory, groupscope | export-CSV C:\data\ADUserGroups.csv`
To Format the result as Table in the console itslef :
Get-ADPrincipalGroupMembership <Username> | select name, groupcategory, groupscope | Format-Table

Troubles with substring, trim, trimend

I'm trying to take an array of email addresses (in the form of username#company.com) which is generated from:
$users = get-MSOLUser -All | where {$_.isLicensed -eq "TRUE" -and $_.Licenses.AccountSKUID -eq "my_license"} | select userprincipalname
And get just the username from each. I start with username#company.com and want to end up with username. I have tried various ways using substring, Trim, TrimEnd, etc and can't get any of them working.
$username = $users | %{$_.substring(0,$users.length - 12)}
$users | %{$_.trimend("#company.com")}
$users | %{$_.trimend(12)}
All of the above give errors including the two below.
Method invocation failed because [Selected.Microsoft.Online.Administration.User] does not
contain a method named substring.
Method invocation failed because [Selected.Microsoft.Online.Administration.User] does not
contain a method named trimend.
What am I doing wrong with the syntax, or is there something else, like a module I haven't imported, or how my syntax is trying to work with an array?
This will return you a list of all usernames (without domain) that fulfills your conditions:
$users = Get-MSOLUser -All |
Where-Object {$_.isLicensed -eq "TRUE" -and $_.Licenses.AccountSKUID -eq "my_license"} |
ForEach-Object { $_.userprincipalname -replace '#.*' }
Well, you need to work with the property, not with the object, so you would probably want to do something like:
select -expandproperty userprincipalname
but that would create an array of userprincipalnames, so no other attributes.
When you run get-MSOLUser you get back an object, with a bunch of properties. When you do select -expandproperty you are getting back only certain property, but not an object itself. You are getting back a system.string object. And that object has all those methods you are trying to invoke.