Powershell problems at value adding for the search loop - powershell

So I got here something that I cant explain better.
$var = "Admin_Group"
Get-ADGroupMembers $var
Works fine, now the issue that is itching me for some time...
$get_AD_Groups = Get-ADGroup -Filter '*' | Select-Object Name
foreach ($item in $get_AD_Groups) {
$get_users = Get-ADGroupMember "$item"| Select-Object Name
}
Now the Get-ADGroupMember in foreach(...) loop is giving me error that the same given string as on top example does not exist
Error:
Get-ADGroupMember : Cannot find an object with identity: '#{Name=Admin_Group}'
Already tried it with '' and with "". Help, thanks :)

So what i found out, and its working it that instead of
Get-ADGroupMember "$item"| Select-Object Name
i use $get_users = $item.Name | Get-ADGroupMember | Select-Object Name
Dont know if this makes sense but it works.

Related

powershell how do I Create/format a dynamic list from a group membership to use in a for each loop

bit of a noob question.
I have the following cmd which grabs the server members of a group which I can copy into a text list. however as the group changes I need to modify the text list manually.
Get-AdGroupMember -identity "Reboot 7pm" | Sort-Object | select name
when I have that output in a text list, the following works fine.
$listpath = "C:\Scripts\servers.txt"
[System.Collections.ArrayList]$list = #(Get-content $listpath)
foreach($ComputerName in $list)
{
Get-Uptime -ComputerName $ComputerName
I want to know if it is possible to use a variable that I can use again in a for each loop. I've tried to do so, however the format of the list is not the same when is goes into a variable, thus the function (get-uptime) against the server doesn't work, anyone know what I can do to format the output so I only get the server name?
EG.
$WSUS_7PM = Get-AdGroupMember -identity "Reboot 7pm" | Sort-Object | select name
PS C:\Windows\system32> $WSUS_7PM
name
----
AXXXXX003
BXXXXX005
CXXXXX006
DXXXXX007
PS C:\Windows\system32> foreach($Name in $WSUS_7PM) {Write-Host $Name}
#{name=AXXXXX003}
#{name=BXXXXX005}
#{name=CXXXXX006}
#{name=DXXXXX007}
so when I run the same cmds as above modified with the variable instead of the text list, I get the following as the server name is obviously incorrect.
$listpath = $WSUS_7PM
[System.Collections.ArrayList]$list = #(Get-content $WSUS_7PM)
foreach($ComputerName in $list)
{
Get-Uptime -ComputerName $ComputerName
WARNING: Unable to connect to #{name=AXXXXX003}
WARNING: Unable to connect to #{name=BXXXXX005}
I hope that makes sense to someone, appreciate the help in understanding what the difference is in the object output.
Thanks
Alzoo
When you use Select-Object name you are creating a list of objects with a name property. You can either expand it ahead of time
$WSUS_7PM = Get-AdGroupMember -identity "Reboot 7pm" | Sort-Object | Select-Object -ExpandProperty name
or reference the name property later
foreach($Name in $WSUS_7PM.name) {Write-Host $Name}

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.

PowerShell foreach loop with embedded if statement yields "cannot accept 'True' as positional parameter"

I'm trying to write a simple PS line to take the exported .csv of AD groups in particular "regions" we have set up, then take the GroupScope (universal vs. global), and depending on the scope of the group, write the "department" attribute as either "Universal" or "Global." The reason for doing so is to help identify between the 2 scopes within SharePoint.
$uni="Universal"
Import-csv \\usershare\user\me\output\groups.csv | foreach {Get-ADGroup -Identity $_.Name -Properties * | Set-ADGroup if($_.GroupScope -eq $uni){-replace #{department=$uni}}}
This is returning the following error message though:
"A positional parameter cannot be found that accepts the argument 'True.'"
I'm probably missing something simple here but I just started out and I'm self-teaching by trial and error mostly. Thanks for any help you can provide!
You're use of the if block is not valid for what you are trying to accomplish, it will only return True or False and Set-ADGroup will not know what to do with that hence the error.
Try this:
$uni="Universal"
$csv = Import-Csv -Path '\\usershare\user\me\output\groups.csv'
foreach($i in $csv)
{
if($i.GroupScope -eq $uni)
{
Get-ADGroup -Identity $i.Name -Properties 'department' |
Set-ADGroup -Replace #{department=$uni}
}
}
I've set properties to only pull department as a smaller scope will speed up the query.

Remove #{ColumnName from Powershell results

I'm relatively new to PowerShell scripting and have mainly been cobbling together different scripts and cmdlets from Googling what I'm trying to do. One problem that I'm unable to Google, or search for on StackExchange, because of the special characters is having all my results come out as #{ColumnName=ColumnData}.
Here's an example script I found somewhere for pulling all the members of an AD group.
$Groups = Get-ADGroup -Filter {Name -like "!GroupName"}
$path = $groups
$myCol = #()
ForEach ($Group in $Groups)
{
$Members = #(Get-ADGroupMember "$Group")
ForEach ($Member in $Members){
try{
$user = get-aduser -identity $member -properties displayname
$MyObject = New-Object PSObject -Property #{
Displayname = $user.Displayname
}
$mycol += $MyObject}
catch {}}
}
Write-Host $MyCol | FL
I'm pretty sure there are better ways to get the members of an AD group but that's not the issue at the moment. The problem is all the data comes out like #{Displayname=Lawrence, Kimberly} and this happens with many of the scripts I've thrown together.
Any ideas on how to write scripts properly so I can just get DisplayName = Lawrence, Kimberly?
I agree your code is complex and it does not need to be. A couple of things that are important to mention is why your output looks the way it does.
You are creating an array of PSCustomObjects which function similar to hash-tables. In the end of your processing you have an array of objects with the property DisplayName. Since you are using Write-Host to display the the contents of $myCol it needs to cast it a string array in order to display it. You would see similar output if you just typed [string[]]$myCol. I should hope that you are doing something else in the processing as like the other answers show you have a very complicated way of getting what you are looking for.
Without beating the horse about those other solutions I will suggest some minor changes to yours as it stands. Your title and last sentence contradict what you are looking for since you want to remove the ColumnName in the title and the last sentence you are looking for output like DisplayName = Name.
Changing the last line will address both of these. If you just want the displaynames on there own
$myCols | Select-Object -ExpandProperty DisplayName
Lawrence, Kimberly
and if you actually want the other format you could do this
$myCols | ForEach-Object{
"DisplayName = $($_.DisplayName)"
}
Again, like the other answers, I stress that your code could use simple overhaul. If you needed to understand why it was working the way it way I hope I helped a little.
This actually has nothing to do with Active Directory; You are creating custom objects, then outputting them directly, and by default that is how PowerShell will format the output if you use Write-Host (which is intended to customize output). If you would like to be more specific about what your output should look like, we can help, but here is an example that outputs the results as just a list of strings, just using Write-Output:
$myCol = #()
$MyObject = New-Object PSObject -Property #{ DisplayName = "Lawrence, Kimberly" }
$myCol += $MyObject
$MyObject = New-Object PSObject -Property #{ DisplayName = "Hello, World" }
$myCol += $MyObject
# The default will show at-symbols, etc: Write-Host $MyCol | FL
Write-Output $myCol
The output will be:
DisplayName
-----------
Lawrence, Kimberly
Hello, World
Try this:
Get-ADGroup -Filter "Name -like '!GroupName'" |
Get-ADGroupMember |
Get-ADUser -Properties DisplayName |
Select-Object DisplayName
When I ran your code, I also got the hashes, even without special characters. Your code is way too unnecessarily complex.

powershell how to remove `{}#` from output. Is there a special command to do it?

I entered gwmi win32_product | select -property name | select -first 1 and output to a file. My result was #{name=Google Talk Plugin}.
How can I get rid of #{}, and name. I only want it to show Google Talk Plugin?
#{} means your exporting an object with properties. Try the -ExpandProperty parameter in Select-Object. You could also combine both select-object commands, like:
gwmi win32_product | select -expandproperty name -first 1
I ran into a problem similar with
$drive = Get-WmiObject Win32_LogicalDisk -ComputerName $servername | Select-Object DeviceID
$drive comes up as #{DeviceID=C:}, #{DeviceID=D:}, ...
Here is my brute force hack at it.
The second Trim statement was because for some reason if I put it in the first Trim it starts to Trim the letters in the Drive =D: becomes :
enter code here
$Asdrive = #() #declared before to get rid of null pointer issue, also to tell PS this is an array not a string
#Write-Host "Trimming for Get-WmiObject"
for($i=0;$i -lt $drive.length; $i++) {
[string]$sdrive = $drive[$i]
[string]$sdrive1 = $sdrive.Trim("#","{","}","D","e","v","i","c","e","I","D")
[string]$sdrive2 = $sdrive1.Trim("=")
$Asdrive += $sdrive2
}
If you're running at least Version 3, you can also use the member enumeration feature and then array slicing to take the first one, instead of using select:
(gwmi win32_product).name[0]
I add some code as I found this question with google.
Frode F. solution is the best one.
If you write out something like:
Get-ADComputer -Filter * -SearchBase $OU | Select-Object Name
you get a proper List of all Computers in an OU. You can also pipe that to a CVS/HTML file and its still nice.
| Export-CSV "mylist.csv"
But if you store it into a variable (array) every name will be wrapped in #{}.
In my case I needed computer names in a variable. Here is the solution thanks to Frodo:
$computerList = Get-ADComputer -Filter * -SearchBase $OU | Select-Object -ExpandProperty Name
Hope it helps someone.
(would add it as comment under the right solution, but I don't have enough reputation to do so)