I am trying to grab the host file entries of servers in mulptiple OUs here to show the host file entries and server names
$OUpath =
'OU=Sales,OU=Servers,OU=_Production,OU=Upgraded,DC=fabrikam,DC=local'
'OU=DCHR,OU=Servers,OU=_Production,OU=Upgraded,DC=fabrikam,DC=local'
'OU=Finance,OU=Servers,OU=Test,OU=Upgraded,DC=fabrikam,DC=local'
$ExportPath = 'c:\servers.csv'
$OUpath | Foreach {
Get-ADComputer -Filter * -SearchBase $OUpath} | Select-object DistinguishedName,DNSHostName,Name,Description | Export-Csv -NoType $ExportPath
Part A up ran fine...How can i get the entries of the results. I am tending towards content but hope to have it all in one script. Any help would be nice.
An alternative to #FoxDeploy's helpful answer, here is how you can do the same using the pipelines with ForEach-Object.
Note that Description is not a default property for Get-ADComputer you will need to add -Properties Description to see it's value.
Another point to consider, by default, if you don't specify the -SearchScope, Get-ADComputer will perform a SubTree search, meaning that it will bring all computers of the specified OU and all computers on all the OUs contained in the Base OU. If you just want to bring the computers in the OU without going down in recursion, you should add -SearchScope OneLevel.
#(
'OU=Sales,OU=Servers,OU=_Production,OU=Upgraded,DC=fabrikam,DC=local'
'OU=DCHR,OU=Servers,OU=_Production,OU=Upgraded,DC=fabrikam,DC=local'
'OU=Finance,OU=Servers,OU=Test,OU=Upgraded,DC=fabrikam,DC=local'
) | ForEach-Object {
Get-ADComputer -Filter * -SearchBase $_ -Properties Description
} | Select-Object DistinguishedName,DNSHostName,Name,Description |
Export-Csv 'c:\servers.csv' -NoTypeInformation
I think the primary issues were the array getting declared incorrectly, and incorrect syntax for the ForEach-Object cmdlet
$OUpath = #(
'OU=Sales,OU=Servers,OU=_Production,OU=Upgraded,DC=fabrikam,DC=local'
'OU=DCHR,OU=Servers,OU=_Production,OU=Upgraded,DC=fabrikam,DC=local'
'OU=Finance,OU=Servers,OU=Test,OU=Upgraded,DC=fabrikam,DC=local'
)
$ExportPath = 'c:\servers.csv'
$OUpath |
ForEach-Object {
Get-ADComputer -Filter * -SearchBase $_ -Properties Description
} |
Select-Object DistinguishedName, DNSHostName, Name, Description |
Export-Csv $ExportPath -NoTypeInformation
You have to use $_ in this context where you were using $OUpath previously. Select-Object can take the the piped output from the ForEach-Object loop rather than being in the loop, which should be more efficient. Likewise for Export-Csv.
As implied by FoxDeply's very good answer that might signal an attempt to use A ForEach(...) loop construct instead of ForEach-Object. But if we are going that route I think it's slightly better to let PowerShell populate the array for us.
$OUpath = #(
'OU=Sales,OU=Servers,OU=_Production,OU=Upgraded,DC=fabrikam,DC=local'
'OU=DCHR,OU=Servers,OU=_Production,OU=Upgraded,DC=fabrikam,DC=local'
'OU=Finance,OU=Servers,OU=Test,OU=Upgraded,DC=fabrikam,DC=local'
)
$Servers =
ForEach( $Path in $OUpath )
{
Get-ADComputer -Filter * -SearchBase $path -Properties Description |
Select-Object DistinguishedName, DNSHostName, Name, Description
}
$Servers | Export-Csv $ExportPath -NoTypeInformation
Alternatively you could skip the Select-Object inside the loop and add $Servers = $Servers | Select-Object ... right after the loop. Although the difference is probably negligible.
With some minor restructuring, this should get you past your issue
$OUpath = (
'OU=Sales,OU=Servers,OU=_Production,OU=Upgraded,DC=fabrikam,DC=local',
'OU=DCHR,OU=Servers,OU=_Production,OU=Upgraded,DC=fabrikam,DC=local',
'OU=Finance,OU=Servers,OU=Test,OU=Upgraded,DC=fabrikam,DC=local')
$ExportPath = 'c:\servers.csv'
$servers = new-object System.Collections.ArrayList
ForEach($path in $OUpath){
$ouServers = Get-ADComputer -Filter * -SearchBase $path | Select-object DistinguishedName,DNSHostName,Name,Description
$servers.AddRange($ouServers) | Out-Null
}
"found $($servers.Count) servers!"
$servers | export-csv $exportPath
I made the list of OU Paths a PowerShell array, then iterate through them using the standalone ForEach loop. Then commit the items to a variable that will persist ($servers) and output the CSV.
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
I'm trying to write a program that lets users to do different kinds of queries on Active Directory. I want to make it in a way that lets them to chose which attributes they want to show in the output, and also filter the output in several ways.
As I don't know during writing the code how many attributes they will chose, it seemd the easiest way to produce a string out of the attributelist, and invoke the string with invoke-expression. This way works perfectly with attributes, but not at all with filters.
I've found several kinds of filter syntaxes but neither works when I put them in a string and try to invoke that with "Invoke-expression"
This:
$time = (Get-Date).Adddays(-(19))
Get-ADUser -Filter {LastLogonTimeStamp -gt $time} -SearchBase 'CN=Users,DC=home,DC=local' -Properties samAccountname, LastLogonDate | Select-Object #{n='Felhasználónév'; e='samAccountName'}, #{n='Utolsó bejelentkezés'; e='LastLogonDate'} | Out-String
Gives me the result I want.
While this:
$time = (Get-Date).Adddays(-(19))
$out = "Get-ADUser -Filter {LastLogonTimeStamp -gt $time} -SearchBase 'CN=Users,DC=home,DC=local' -Properties samAccountname, LastLogonDate | Select-Object #{n='Felhasználónév'; e='samAccountName'}, #{n='Utolsó bejelentkezés'; e='LastLogonDate'} | Out-String"
Write-Host $out
Invoke-Expression $out
Gives me the following result:
Get-ADUser -Filter {LastLogonTimeStamp -gt 05/05/2019 19:05:46} -SearchBase 'OU=Testing,DC=home,DC=local' -Properties samAccountname, LastLogonDate | Select-Object #{n='Username'; e='samAccountName'}, #{n='Last Logon'; e='LastLogonDat
e'}
Get-ADUser : Error parsing query: 'LastLogonTimeStamp -gt 05/05/2019 19:05:46' Error Message: 'Operator Not supported: ' at
position: '26'.
At line:1 char:1
+ Get-ADUser -Filter {LastLogonTimeStamp -gt 05/05/2019 19:05:46} -Sear ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ParserError: (:) [Get-ADUser], ADFilterParsingException
+ FullyQualifiedErrorId : ActiveDirectoryCmdlet:Microsoft.ActiveDirectory.Management.ADFilterParsingException,Microsoft
.ActiveDirectory.Management.Commands.GetADUser
Why does every other command works perfectly when invoking them from a string, but not this one? Is there any other way to filter the result? At first I wanna stick to filtering before the query, and not with the where clause, but I'm gonna try that too, if filtering won't work.
It feels stupid to answer my own question, but I think I found the answer.
Placing escape character before the variable did the trick.
$time = (Get-Date).Adddays(-(19))
$out = "Get-ADUser -Filter {lastlogontimestamp -gt `$time} -SearchBase 'CN=Users,DC=home,DC=local' -Properties samAccountname, LastLogonDate | Select-Object #{n='Felhasználónév'; e='samAccountName'}, #{n='Utolsó bejelentkezés'; e='LastLogonDate'} | Out-String"
Write-Host $out
$expr = Invoke-Expression $out
$expr
Returns
Felhasználónév Utolsó bejelentkezés
-------------- --------------------
Administrator 2019. 05. 24. 18:18:28
I had a similar situation, but mine was specific to $true $false parameters that are $true if present, $false if absent for [switch] type [params]. I had never needed to override the default params, because those were originally intended for single-use/manual invocation from the command line.
Invoke-Expression simplified calling .ps1 files as subroutines, but this would work directly from the command line console
\temp\00405-LoadW.ps1 -skipinit -showbanner:$false | Out-File -filepath 'c:\temp\today\00405-LoadW.log'
while this would not work when called inside a .ps1 file:
Invoke-Expression "\temp\00405-LoadW.ps1 -skipinit -showbanner:$false | Out-File -filepath 'c:\temp\today\00405-LoadW.log'"
This post (directly above) has the solution, the back-tick
`
This works both on the command console and from inside a .ps1:
Invoke-Expression "\temp\00405-LoadW.ps1 -skipinit -showbanner:`$false | Out-File -filepath 'c:\temp\today\00405-LoadW.log'"
PS: More time spent on figuring out how to escape the back-tick here than the actual answer.
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.
I currently have the following script that works well for gathering a list of installed programs from a list of remote computers.
$PCListOld = Get-Content F:\PCList-Old.txt
ForEach ($PC in $PCListOld)
{
$AppList = Get-WmiObject -Computer $PC Win32_Product | Sort-Object Name
$AppList | Export-CSV C:\~Scripts\AppLists\$PC.csv
}
However, I really only need the Name property in $AppList, but if I simply pipe $AppList.Name to Export-CSV, I don't get the same output in the csv as I would have on the screen. Can someone give me some advice on how I should edit this so I can just get the Name value exported to the csv file?
Thanks in advance for the help.
Restrict the result properties to just Name via Select-Object:
foreach ($PC in $PCListOld) {
Get-WmiObject -Computer $PC Win32_Product |
Sort-Object Name |
Select-Object Name |
Export-Csv C:\~Scripts\AppLists\$PC.csv
}