This question already has answers here:
How to get an object's property's value by property name?
(6 answers)
Closed 5 years ago.
I am working on a script which takes Hostnames from a CSV, Files them against Get-ADComputer and then saves certain Objects in certain columns of the original CSV.
While the solution seems like a basic Task (code below), my problem is, that the Output of Get-ADComputer always (you can see I played around with Out-String but also tried other formatting options) contains a lot of NewLine characters or other formatting issues which make the CSV confusing.
Clear-Host
Import-Module ActiveDirectory
$import = Import-Csv 'XXX' -Delimiter ';'
Foreach ($row in $import){
$hostname = $row.HOSTNAME
if($hostname.length -gt 3){
$computer = Get-ADComputer -Filter {Name -like $hostname} -Properties LastLogonDate, LastLogonTimeStamp
$row.AD_LastLogon.ToString() = $computer | Select-Object LastLogonDate | Select-Object -first 1 | FT -HideTableHeaders | Out-String
$row.AD_LLTimestamp = $computer | Select LastLogonTimestamp |Select-Object -first 1 | FT -HideTableHeaders | Out-String
}
}
$import | Export-Csv 'XXX' -Delimiter ';' -NoType
My question now is, if anyone could help with a method to get the bare string result of for example Get-ADComputer's LastLogonDate, without any formatting or headers included.
Thanks in advance!
Use the -ExpandProperty parameter of Select-Object to extract just the parameter you want. You can only specify one parameter to exapand at a time.
$row.AD_LastLogon = $computer | Select-Object -ExpandProperty LastLogonDate -First 1 | Out-String
$row.AD_LLTimestamp = $computer | Select-Object -ExpandProperty LastLogonTimestamp -First 1
I don't believe the -First 1 should be necessary. Get-ADComputer shouldn't be finding multiple computers with the same name.
Also, you shouldn't need to retrieve both LastLogonDate and LastLogonTimestamp. The former is the same value as the latter, just converted to a DateTime from the irritating NT Time Epoch that LastLogonTimestamp uses. Have you got a system that requires both?
Finally, just a note but this:
$row.AD_LastLogon.ToString() = $computer | [...]
It doesn't make sense. You can't assign a value to a method. I would be surprised if that didn't error or otherwise do nothing at all.
Related
I am trying to write a powershell script to check all of the online computers and then make it one neat column Here is the code I have so far...
$computers = get-adcomputer -LDAPFilter "(Name=SDA000*)" | Select-Object -Property Name
$computers1 = get-adcomputer -LDAPFilter "(Name=SDA005*)" | Select-Object -Property Name
$computers2 = get-adcomputer -LDAPFilter "(Name=SDA006*)" | Select-Object -Property Name
$computers3 = get-adcomputer -LDAPFilter "(Name=SDA007*)" | Select-Object -Property Name
$computers4 = ($computers) + ($computers1) + ($computers2) + ($computers3)
[array]$online = #($computers4.Name | % {test-connection -erroraction silentlycontinue -Count 1 $_})
$wIw = $online | Select-Object Address
$wIw
But the output always leaves the top 3 lines with extraneous data I don't want. i.e
Address
-------
SDA0003
SDA0007
SDA000B
SDA000C
SDA0050
SDA0051
SDA0054
SDA0057
SDA005F
SDA0061
SDA006B
SDA006D
SDA0076
I can write it to a text file and then pipe it to select-object -skip 3, but that does not seem to work with a variable.
thanks for any advice.
What you are seeing is the header (e.g. the "Address" property). To output it to the screen without the header, you can use the -HideTableHeaders in a Format-Table command:
...
$wIw = $online | Select-Object Address
$wIw | Format-Table -HideTableHeaders
Ohh yes, that treat is sometimes quit helpful but most of the time it is in the way. Here is how I get rid of it:
$computers = (get-adcomputer -LDAPFilter "(Name=SDA000*)" | Select-Object -Property Name).name
Looks like what you want can be done easier like this:
$wIw = (Get-ADComputer -LDAPFilter "(Name=SDA00*)" |
Where-Object { ($_.Name | Test-Connection -Count 1 -Quiet -ErrorAction SilentlyContinue) }).Name
It has been many moons since I have last done this and I am having problems exporting some commands to CSV. The biggest one that is getting me right now is
$ADGroupList = Get-ADGroup -Filter * -property * | Select Name -ExpandProperty Name | Sort
ForEach($Group in $ADGroupList)
{
Write-Host "Group: "$Group.Name
Get-ADGroupMember -Identity $Group | Select Name -ExpandProperty Name | Sort
Write-Host ""
}
Export-Csv -path "c:\Temp\test675.csv"
Works fine with out trying to export but the second I try to export the command will run and either generate a blank file or no file at all.
I am able to run other commands with out a issue exporting them to csv. Thanks for any help in advance.
Tim,
From what I can see you're not giving Export-Csv anything to write. Try this:
$ADGroupList = Get-ADGroup -Filter * -property * | Select Name -ExpandProperty Name | Sort
ForEach($Group in $ADGroupList)
{
Write-Host "Group: "$Group.Name
Get-ADGroupMember -Identity $Group |
Select Name -ExpandProperty Name |
Sort |
Export-Csv -path "c:\Temp\test675.csv"
Write-Host ""
}
I'd test this but I don't have access to ActiveDirectory.
Also the Write-Hosts you probably don't want in the .csv file as they won't play well with the format, headers & columns.
HTH
How to get displayname from direct reports attribute ?
Get-ADUser $foo -Properties * | select #{Name="directreports";Expression={($_.directreports | %{(Get-ADUser $_).displayname}) -Join ";"}}
Output :
directreports
-------------
;;;;;;;;;;;;;;;;;;
ISSUE resolved :
Get-ADUser $foo -Properties * | select #{Name="directreports";Expression={($_.directreports | %{(Get-ADUser $_).name}) -Join ";"}}
Apologies for misreading your question, try out the below and let me know if this does what you want it to do?
Get-ADUser $foo -Properties * | Select-Object -ExpandProperty DirectReports | ForEach-Object { Get-ADUser -Identity $_ | Select-Object Name }
You can always add on | Export-CSV -Path "c:\temp\directreports.csv" -NoTypeInformation at the end to get this out of course.
On your original code, the easiest way I found to expand out the list of direct reports was to do the select on it's own and then pipe into a foreach, rather than trying to do it all in one as an expression.
Also, DisplayName is not a default property returned by Get-ADUser, so this is why I used the Name property instead in my suggested solution.
Thanks!
I am attempting to use the -ExpandProperty feature in PowerShell to stop the header appearing in the output and format the date without minutes and seconds. This is just to get the created date for an AD Object:
Get-ADComputer -Server $Server -Identity BlahBlah -Properties Created |
Select-Object -ExpandProperty #{Name="Created";Expression={$_.Created.ToString("yyyy-MM-dd")}}
This does not produce a result, only if I exclude the "-ExpandProperty" part will it produce the right date format BUT includes the header "Created" which I don't want.
Any ideas please?
I don't have access to an AD at the moment, but this could be what you are after
Updated
Get-ADComputer -Server $Server -Identity BlahBlah -Properties Created | Select-Object Created | ForEach-Object {$_.Created.ToString("yyyy-MM-dd")}
To complement LotPings' helpful answer, which offers effective solutions:
As for why your code didn't work:
While Select-Object's -Property parameter accepts hashtables that define calculated properties (such as in your code), the -ExpandProperty parameter only accepts a property name, as a string.
Therefore, your hashtable is simply stringified, resulting in string literal System.Collections.Hashtable, causing Select-Object to complain, given that there is no property by that name.
The purpose of -ExpandProperty is to output just a property value rather than a custom object with that property.
You therefore do not need a detour via Select-Object, and can just use the value-outputting script block - { $_.Created.ToString("yyyy-MM-dd") } - directly with ForEach-Object instead, as shown at the bottom of LotPings' answer.
However, there is an obscure feature that you forgo by using ForEach-Object: Select-Object allows combining -ExpandProperty with -Property, in which case the properties specified via -Property are added as NoteProperty members to the value of the property specified via -ExpandProperty:
PS> $val = [pscustomobject] #{ one = 'uno'; two = 2 } |
Select-Object -ExpandProperty one -Property two; $val; $val.two
uno
2
Note how the output string value, 'uno' has a copy of the input object's .two property attached to it.
To emulate that with ForEach requires more work:
PS> $val = [pscustomobject] #{ one = 'uno'; two = 2 } | ForEach-Object {
$_.one + '!' | Add-Member -PassThru two $_.two
}; $val; $val.two
uno!
2
In PowerShell there nearly always is more than one solution to a problem-
(Get-ADComputer -Server $Server -Identity BlahBlah -Properties Created |
Select-Object #{N="Created";E{$_.Created.ToString("yyyy-MM-dd")}} ).Created
or
Get-ADComputer -Server $Server -Identity BlahBlah -Properties Created |
Select-Object #{N="Created";E{$_.Created.ToString("yyyy-MM-dd")}} |
Select-Object -Expand Created
Parameter names can be shorted as long as they are uniquely identifiable and there are also shortcuts (uppercase letters) so -EA is -ErrorAction
A calculated property does IMO make no sense here as it is the only output, so this should do also:
Get-ADComputer -Server $Server -Identity BlahBlah -Properties Created |
ForEach-Object {$_.Created.ToString("yyyy-MM-dd")}
This question already has answers here:
How do I write the value of a single property of a object?
(2 answers)
Closed 4 years ago.
I have the following bit of code
$date = ((get-date).addmonths(-3))
Get-ADUser -Filter * -Properties whenChanged| Where-Object {$_.whenChanged -ge $date} | select name
This works fine and gives me a nice list of users that have not had there account updated in 3 months. But I need this as a log in script so I want it to say logicaly
if ((get-aduser <name> -Properties whenChanged) -ge $date) {do something} else {do nothing}
When ever I try this i get..
$c = Get-ADUser street | Where-Object {$_.whenChanged -ge $date} | select whenchanged
write-host $c
#{whenchanged=07/09/2015 17:00:30}
I know there is a magic bit of syntax to make it work and I would be great ful for any pointers.
Because the Result is an [Hashtable] Type you need to add the -ExpandProperty to the Select-Object Cmdlet to expand it, like this:
$c = Get-ADUser street -Properties whenChanged | Where-Object {$_.whenChanged -ge $date} |
Select -ExpandProperty whenchanged
write-host $c
-ExpandProperty
Specifies a property to select, and indicates that an attempt should be made to expand that property. Wildcards are permitted in the property name.
For example, if the specified property is an array, each value of the array is included in the output. If the property contains an object, the properties of that object are displayed in the output.