How do I fix this script? - powershell

I am trying to get this short script to work and I don't understand why, PowerShell gives somewhat garbled and useless error messages!
Script:
$us = Read-Host 'Enter Your User Group Name:' |Get-ADGroup -Filter {name -like "*$us*"} -Properties Description,info | Select Name | Sort Name
Error:
Get-ADGroup : The input object cannot be bound to any parameters for the
command either because the command does not take pipeline input or the input
and its properties do not match any of the parameters that take pipeline input.
At line:1 char:42
+ ... ser Name:' |Get-ADGroup -Filter {name -like "*$us*"} -Properties Desc ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (River:PSObject) [Get-ADGroup], ParameterBindingException
+ FullyQualifiedErrorId : InputObjectNotBound,Microsoft.ActiveDirectory.Management.Commands.GetADGroup

You can't pipe your string definition to the filtered commandlet in that manner. Declare the variable first.
Once you;ve done that, filter as required then select the properties you need (Description property is needed as it isn't returned by default by the commandlet whilst the Name property is).
$us = Read-Host 'Enter Your User Group Name:'
Get-ADGroup -filter "Name -like '*$us*'" -Properties Description | Select-Object Name , Description | Sort-Object Name

The problem is $US is not set until the end of the pipeline, and therefore is empty.
Try:
$us = Read-Host 'Enter Your User Group Name:' | # get the name
%{"*$($_)*"} | # Add the asterisk wildcard.
%{Get-ADGroup -filter {name -like $_}} | # read from AD
Select Name |
Sort Name
This will ask you for the group name, and then save the results to the pipeline (not to $us). The pipeline value is used to then add your asterisks and then again output the value to the pipeline, before the pipeline is then used for the Get-Adgroups commmand.
Once the results of the lookup is returned, it is cleaned up, and reduced to just name, then sorted to give you a list of names in sorted order.
The "-Properties Description,info" isn't needed because all you want is the name, so why requested description or info fields?
I just tested this, and despite what Ansgar Wiechers said, this does work. If this answer helps you, please vote it up.

Related

Powershell Filter doesn't accept comma

I try to use the Get-User command with a simple Filter.
Get-User -Filter "(Manager -eq 'Max, Mustermann')"
The problem is that i get this exception:
Cannot bind parameter 'Filter' to the target. Exception setting "Filter": "The value "Max, >Mustermann" could not be converted to type
Microsoft.Exchange.Data.Directory.ADObjectId.
"(Manager -eq 'Max, Mustermann')" at position 34."
In C:\Users\JAKO\AppData\Local\Temp\tmp_4vtu0s13.ymv\tmp_4vtu0s13.ymv.psm1:38356 Zeichen:9
$steppablePipeline.End()
~~~~~~~~~~~~~~~~~~~~~~~~
CategoryInfo : WriteError: (:) [Get-User], ParameterBindingException
FullyQualifiedErrorId : >ParameterBindingFailed,Microsoft.Exchange.Management.RecipientTasks.GetUser
As far as I understand the Problem its because of the comma, so i tryed some workaorunds.
Get-User -Filter "(Manager -like 'Max, Mustermann')"
Here I dont get an exception but there are no Users that get returned.
Get-User -Filter "(Manager -eq 'Max"," Mustermann')"
The same as with the other workaround. No exception but no Users are Matching.
I also made sure that i have Users that would match this specift query, by using this command
Get-User -Filter | Format-List Manager
How can I write my Filter input so it matches "Max, Mustermann"?
From the filtering documentation for the Manager attribute:
This filter requires the distinguished name or canonical distinguished name of the manager (a mailbox or mail user). For example, Get-User -Filter "Manager -eq 'CN=Angela Gruber,CN=Users,DC=contoso,DC=com'" or Get-Mailbox -Filter "Manager -eq 'contoso.com/Users/Angela Gruber'".
To find the distinguished name of a manager, replace with the name, alias, or email address of the recipient, and run this command: Get-Recipient -Identity "<RecipientIdentity>" | Format-List Name,DistinguishedName.
So now we know why the filter isn't working (a distinguished name is expected), and how to obtain the correct value (by using Get-Recipient):
# Fetch manager's user account object
$targetUser = Get-Recipient -Filter "SimpleDisplayName -eq 'Max, Mustermann'"
# Fetch reports
Get-User -Filter "Manager -eq '$($targetUser.DistinguishedName)'"

Replace legacyExchangeDN value in ADSI via PowerShell

I'm looking to correct a small issue in AD where the field I mentioned has a space in the value.
For example:
legacyExchangeDN : /o= First Organization/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=6131a3a42ca946b98cc146345cfd0c2e-Ron E
Should look like this:
legacyExchangeDN : /o=First Organization/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=6131a3a42ca946b98cc146345cfd0c2e-Ron E
This is affecting multiple users and I can manually update the value in the AD Attribute Editor, but I was hoping to be able to automate this.
Here's what I have so far:
#List all users to check existing values
$ADUserList = Get-ADUser -Filter* -Properties * | fl name, EmailAddress, legacyExchangeDN
#Replace value with space with value without space
Set-ADUser reyer -Replace #{legacyExchangeDN="/o= ","/o="}
The second line produces the following error:
Set-ADUser : Multiple values were specified for an attribute that can have only one value
At line:1 char:1
+ Set-ADUser reyer -Replace #{legacyExchangeDN="/o= ","/o="}
It feels like I'm missing something easy here, but I cannot find it. I am testing this with one user. I would like to replace the value against all remaining users in one script once tested. If I could target just the users that match the criteria of having a space in the field that would surely be helpful for either storing it or piping that over.
My final result would look like:
Target users with a space(s) present in the text value of the legacyExchangeDN → /o=
Replace just the /o= with /o= while preserving the remainder of the text value → /o=First Organization/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=6131a3a42ca946b98cc146345cfd0c2e-Ron E
$Users = Get-ADUser -Filter { legacyExchangeDN -like '*/o= *' } -Properties #('name','EmailAddress','legacyExchangeDN')
ForEach ($User in $Users)
{
$Replace = $User.legacyExchangeDN -replace '/o=\s','/o='
Set-ADUser -Identity $User -Replace #{ legacyExchangeDN = $Replace }
Write-Host ('Updated "{0}" ({1}) to "{2}"' -f
#($User.name,$User.EmailAddress,$Replace))
}
This will be faster as well. The mantra is: Filter Left, Format Right. Set-ADUser takes an ADUser object. -Replace takes a [HashTable] where you're assigning a new value to the named property (as it appears in LDAP).
(update: removed pipeline for foreach)
To implement logging, replace Write-Host with:
'Updated "{0}" ({1}) to "{2}"' -f #($User.name,$User.EmailAddress,$Replace) |
Out-File -FilePath "$env:UserProfile\ADChanges.txt" -Append

calling a variable in select -expandproperty

I'm trying to make a report that lists a server name, vm name, and notes section from the vm but I cannot seem to get this code to run, it always gives me this error:
Select-Object : Cannot convert 'System.Object[]' to the type
'System.String' required by parameter 'ExpandProperty'. not supported.
At C:\Cooper\Jobs\Get-VmNotes - Copy.ps1:32 char:48 + get-vm -server
FA0150 | Select -expandproperty $server, Name, Notes +
~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidArgument:
(:) [Select-Object], ParameterBindingException +
FullyQualifiedErrorId :
CannotConvertArgument,Microsoft.PowerShell.Commands.SelectObjectCommand
I can get the vmname and notes to output together but I just want to have a column that lists the vcenter server it is associated with.
Expand property is like the same as saying (Get-VM -Server FA0150).Name. It expands the property name you are selecting. You were trying to expand 3 properties (System.Object[]), but it is looking for just a string name of the property you want to expand. Use -Property instead.
get-vm -server FA0150 | Select-Object -Property Name,Notes
get-vm -server FA0150 | Select-Object -Property Name,Notes | Format-Table -Autosize
To also include the server name I made it into a script form since it can no longer be a one-liner:
[CmdletBinding()]
Param ( $Server )
$VMs = Get-VM -Server $Server
$VMs | Select-Object -Properties #(
#{ Label = 'Server';Expression = { $Server } }
'Name'
'Notes'
)
I found a solution to my problem using New-ViProperty. The only problem is now it creates four separate csv files and I want to combine them all into one based on the filename, keeping the same format, and delete the four others based on their filename. Is there an easy way to do this?

PowerShell - Return value of AD User's First and Last name

I am attempting to pull a users first and last name from AD using PowerShell.
The commands:
$GivenName = Get-ADUser -Identity $User | select GivenName
Write-Host $GivenName
returns a value of: #{GivenName=Bruce}
I then tried to reduce the string down to just the part i need with the following commands:
$First = $GivenName.Replace("#{GivenName=","")
$First = $First.Replace("}","")
This should strip away all except for the string 'Bruce'
Instead I get this following error:
Method invocation failed because [Selected.Microsoft.ActiveDirectory.Management.ADUser] does not contain a method named 'Replace'.
At C:\Users\john.ring\Documents\Scripts\UpdateADUsers.ps1:10 char:5
+ $First = $GivenName.Replace("#{GivenName=","")
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (Replace:String) [], RuntimeException
+ FullyQualifiedErrorId : MethodNotFound
My Google-fu has failed to find a solution. Any suggestion on how to correct the error or a better way to pull the users first name would be greatly appreciated.
When you pipe objects to Select-Object [propertyname(s)], the Select-Object cmdlet creates a new object for you, with the properties from the input object that you specified. This object in turn ends up being rendered as #{PropertyName1=PropertyValue1[;PropertyNameN=PropertyValue2]} when converted to a string.
To grab the value of a single property, and nothing else, use the -ExpandProperty parameter:
$GivenName = Get-ADUser -Identity $user |Select-Object -ExpandProperty GivenName
Since you need multiple properties from the same user, better store the the user in a variable and use the . dereference operator to access the GivenName and Surname properties:
$UserObject = Get-ADUser -Identity $user
$GivenName = $UserObject.GivenName
$Surname = $UserObject.Surname
GivenName is a user object attribute in Active Directory. You're storing the results of your query in a PowerShell object called $GivenName, however the two are not the same. To reference the user's given name, you need to reference the GivenName property of the PowerShell object. $GivenName.GivenName is what you are looking for.
It might be less confusing if you store the results of your AD query in an object named $User instead, so $User.GivenName is how you would reference the given name property.

How to list AD group membership for AD users using input list?

I'm fairly new PS user... Looking for some assistance with a powershell script to obtain list of security groups user is member of.
To describe what I need:
I have input list (txt file) with many users (samaccountnames). Every name is on a new line.
I need the script to search these names in AD - whole forest, not just one single domain
output should look like "samaccountname" and list of groups this account is member of in one line, so I can sort it in excel
This is the script I have:
$users = Get-Content C:\users.txt
ForEach ($User in $users) {
$getmembership = Get-ADUser $User.Users -Properties MemberOf | Select -ExpandProperty memberof
$getmembership | Out-File -Append c:\membership.txt
}
but it throws me an error:
Get-ADUser : Cannot validate argument on parameter 'Identity'. The argument is null. Supply a non-null argument and try the command again.
At line:4 char:28
+ $getmembership = Get-ADUser <<<< $User.Users -Properties MemberOf | Select -ExpandProperty memberof
+ CategoryInfo : InvalidData: (:) [Get-ADUser], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.GetADUser
Anyway, this script wouldn't search the whole forest.
Sample input list:
username1
username2
username3
username4... etc
Sample output list
username1;group1;group2;group3
username2;group1;group2;group3;group4... etc or something similar
Any help would be greatly appreciated.
First: As it currently stands, the $User variable does not have a .Users property. In your code, $User simply represents one line (the "current" line in the foreach loop) from the text file.
$getmembership = Get-ADUser $User -Properties MemberOf | Select -ExpandProperty memberof
Secondly, I do not believe you can query an entire forest with one command. You will have to break it down into smaller chunks:
Query forest for list of domains
Call Get-ADUser for each domain (you may have to specify alternate credentials via the -Credential parameter
Thirdly, to get a list of groups that a user is a member of:
$User = Get-ADUser -Identity trevor -Properties *;
$GroupMembership = ($user.memberof | % { (Get-ADGroup $_).Name; }) -join ';';
# Result:
Orchestrator Users Group;ConfigMgr Administrators;Service Manager Admins;Domain Admins;Schema Admins
Fourthly: To get the final, desired string format, simply add the $User.Name, a semicolon, and the $GroupMembership string together:
$User.SamAccountName + ';' + $GroupMembership;
Get-ADPrincipalGroupMembership username | select name
Got it from another answer but the script works magic. :)
Or add "sort name" to list alphabetically
Get-ADPrincipalGroupMembership username | select name | sort name
Everything in one line:
get-aduser -filter * -Properties memberof | select name, #{ l="GroupMembership"; e={$_.memberof -join ";" } } | export-csv membership.csv
The below code will return username group membership using the samaccountname. You can modify it to get input from a file or change the query to get accounts with non expiring passwords etc
$location = "c:\temp\Peace2.txt"
$users = (get-aduser -filter *).samaccountname
$le = $users.length
for($i = 0; $i -lt $le; $i++){
$output = (get-aduser $users[$i] | Get-ADPrincipalGroupMembership).name
$users[$i] + " " + $output
$z = $users[$i] + " " + $output
add-content $location $z
}
Sample Output:
Administrator Domain Users Administrators Schema Admins Enterprise Admins Domain Admins Group Policy Creator Owners
Guest Domain Guests Guests
krbtgt Domain Users Denied RODC Password Replication Group
Redacted Domain Users CompanyUsers Production
Redacted Domain Users CompanyUsers Production
Redacted Domain Users CompanyUsers Production