I'm trying to simply get a list of computers and their OU's from a CSV file of computer names
Add-PSSnapin quest.activeroles.admanagement
$results = #()
$computers = Get-Content "computers.csv"
foreach ($computer in $computers)
{
$results += Get-QADComputer $computer | select name, parentcontainer
}
$results = Export-CSV -path "computerswithous.csv"
But it errors out asking me to supply values. How can I simply output this data to a CSV file?
You did not include it in the post but is this what you were getting:
cmdlet Export-Csv at command pipeline position 1
Supply values for the following parameters:
InputObject:
Simple answer is this line
$results = Export-CSV -path "computerswithous.csv"
Should most likely be this
$results | Export-CSV -path "computerswithous.csv"
In your example Export-CSV has no input data which is what your prompt (not error) is requesting. You actually want to pipe the $results to the CSV file.
You also could do away with that construct as well and just use standard pipeline to get what you are looking for.
Add-PSSnapin quest.activeroles.admanagement
Get-Content "computers.csv" | ForEach-Object{Get-QADComputer $_} |
Select Name,ParentContainer | Export-CSV -Path "computerswithous.csv" -NoTypeInformation
You don't need that intermediate collection ($results) at all. Just wrap the foreach loop in a sub-expression, and send it on to the pipeline.
Add-PSSnapin quest.activeroles.admanagement
$computers = Get-Content "computers.csv"
$(foreach ($computer in $computers)
{
Get-QADComputer $computer | select name, parentcontainer
}) | Export-CSV -path "computerswithous.csv"
Related
I have the following PowerShell code that should run and fetch the last login for the list of UPNs:
$UPNList = get-content c:\temp\users.txt
foreach ($User in $UPNList)
{
Start-Sleep -Milliseconds 1000
$result = Get-AzureADAuditSignInLogs -Filter "UserPrincipalName eq '$User'" -Top 1 | Select-Object CreatedDateTime, UserPrincipalName, IsInteractive, AppDisplayName, IpAddress, TokenIssuerType, #{Name = 'DeviceOS'; Expression = {$_.DeviceDetail.OperatingSystem}}
$result | Export-Csv -Path 'c:\temp\results.txt' -NoTypeInformation -Append
}
However, the "results.txt" file is empty when there is more than one (1) user in the input file.
If there's a single user, results are correctly returned.
How can I ensure the results are provided for all users?
Also, if the user did not log in at all, for example completely new account, how do I ensure that the UPN is still populated in the "results" file, but the rest of the details are empty?
Thank you.
Try not to write out to the output file in every iteration, but have PowerShell collect the objects you output inside the loop and then create the csv file:
# get the list of UPN's and skip empty lines
$UPNList = Get-Content -Path 'c:\test\users.txt' | Where-Object { $_ -match '\S' }
# loop through the list and collect the data in variable $result
$result = foreach ($User in $UPNList) {
# output the wanted data
Get-AzureADAuditSignInLogs -Filter "UserPrincipalName eq '$User'" -Top 1 |
Select-Object CreatedDateTime, UserPrincipalName, IsInteractive, AppDisplayName, IpAddress,
TokenIssuerType, #{Name = 'DeviceOS'; Expression = {$_.DeviceDetail.OperatingSystem}}
}
# now write the collected data to CSV file in one go
$result | Export-Csv -Path 'c:\test\results.csv' -NoTypeInformation
You may also try to do the filtering afterwards like below (could be slower than above code though)
# get the list of UPN's and skip empty lines
$UPNList = Get-Content -Path 'c:\test\users.txt' | Where-Object { $_ -match '\S' }
# filter with Where-Object afterwards and pipe through to the Export-Csv cmdlet
Get-AzureADAuditSignInLogs -All $true | Where-Object { $UPNList -contains $_.UserPrincipalName } |
Select-Object CreatedDateTime, UserPrincipalName, IsInteractive, AppDisplayName, IpAddress,
TokenIssuerType, #{Name = 'DeviceOS'; Expression = {$_.DeviceDetail.OperatingSystem}} |
Export-Csv -Path 'c:\test\results.csv' -NoTypeInformation
I tried to reproduce the same in my environment and got below results:
Initially, I checked with one user in users.txt file like this:
I ran the same script as you and got the response like below:
$UPNList = get-content c:\test\users.txt
foreach ($User in $UPNList)
{
Start-Sleep -Milliseconds 1000
$result = Get-AzureADAuditSignInLogs -Filter "UserPrincipalName eq '$User'" -Top 1 | Select-Object CreatedDateTime, UserPrincipalName, IsInteractive, AppDisplayName, IpAddress, TokenIssuerType, #{Name = 'DeviceOS'; Expression = {$_.DeviceDetail.OperatingSystem}}
$result | Export-Csv -Path 'c:\test\results.txt' -NoTypeInformation -Append
}
Output:
In results.txt file, I got the details of that user successfully like below:
Now I tried including more UPNs in users.txt file like below:
When I ran the same script, the results.txt file is empty as below:
Please note that, the response in results.txt file differs based on how you are giving input in users.txt file.
I tried changing the format of giving input in users.txt file like below:
Now, when I ran the script again, I got the details of those users successfully like below:
So, make sure to give input for users.txt file in correct format.
If the user did not log in at all, it's not possible to get their details using Get-AzureADAuditSignInLogs command.
Normally, you can make use of Get-AzureADUser command to get any user details.
could you please help me to correct this script (gathered by pieces from internet) or better change logic how it should work (not working currently). The goal is to get pc's where only one folder exist (oracle11) and not both (11+12) and export it to csv. Oracle is a real pain in the ....
Thank you in advance for your advice.
Import-Module ActiveDirectory
$computers = Get-ADComputer -Filter * -Properties * | Select -Property Name
$output = #()
#$computers = get-adcomputer -filter * | Select-Object -Expand Name | foreach-object {
Foreach ($Computer in $computers){
if ( (test-path "\\$Computer\C$\oracle\product\11.2.0\" ) -and !( test-path "\\$Computer\C$\oracle\product\12.2.0" )) {
$output += $Computer
}
}
$output | Export-Csv -NoTypeInformation -Path c:\temp\test.csv
The problem is that the path strings you construct inside the loop are not as you expect.
When you pipe the output from Get-ADComputer to Select-Object -Property Name, it creates a new object with a single property Name for each input object.
When you then implicitly convert one of these objects to a string, the resulting value is going to be "#{Name=Computer01}", instead of just "Computer01".
You can observe this yourself, by calling Write-Host instead of Test-Path:
Get-ADComputer -Filter * |Select-Object -Property Name |ForEach-Object {
Write-Host "\\$_\C$"
}
To extract just the value of the Name property from each ADComputer, use ForEach-Object -MemberName instead of Select-Object -Property:
$computerNames = Get-ADComputer -Filter * -Properties * | ForEach-Object -MemberName
$output = #()
foreach($ComputerName in $computerNames){
if ( (Test-Path "\\$ComputerName\C$\oracle\product\11.2.0\" ) -and !( Test-Path "\\$ComputerName\C$\oracle\product\12.2.0" )) {
$output += $ComputerName
}
}
$output | Export-Csv -NoTypeInformation -Path c:\temp\test.csv
Note that passing -Properties * to Get-ADComputer is unnecessary, the object name is always part of the default property set sent back by the Get-AD* cmdlets.
I'm trying to Get the Name, Manufacturer, and model of computers so i can distinguish what computers are out of warranty in AD.
I'm trying to do this by getting the computer names and putting there info into the corresponding .csv file but this fails and puts 1 ou to multiple .csv files and then moves to the second ou and does the same thing?
$myMultiArray = #(("OU=Domain Controllers,DC=FABRIKAM,DC=COM"),
("OU=Computers,DC=FABRIKAM,DC=COM"))
$myFileArray = #(("D:\VS-Code\Powershell\AD_Computer_Management\OUs\Domain
Controllers.csv"),("D:\VS-
Code\Powershell\AD_Computer_Management\OUs\Computers.csv"))
foreach ($MultiOU in $myMultiArray) {
Get-ADComputer -Filter * -SearchBase $MultiOU -SearchScope 2 | Select-object Name | Out-File -FilePath "D:\VS-Code\Powershell\AD_Computer_Management\OUs\garbage.csv"
For ($i = 0; $i – $myFileArray.Length - 1; $i++) {
Write-Host $myMultiArray[$i]
[string[]]$cnArray = Get-Content -Path 'D:\VS-Code\Powershell\AD_Computer_Management\OUs\garbage.csv'
Write-Host $OU
if ($i -eq $i) {
foreach($CN in $cnArray){
Get-WmiObject -Class:Win32_ComputerSystem -ComputerName $OU | Format-List -Property Name, Manufacturer, Model | Out-File -FilePath $myFileArray[$1]
}
}
}
}
I've tried multiple variations of different loops and if statements.
I think there are two things:
Out-File -FilePath $myFileArray[$1]
Should be:
Out-File -FilePath $myFileArray[$i]
And also you might need to append:
Out-File -FilePath $myFileArray[$i] -Append
There are a couple of things wrong in your code, like $i – $myFileArray.Length, which should be $i –lt $myFileArray.Length.
Then there is Out-File -FilePath $myFileArray[$1] as Bernard Moeskops already mentioned.
Also your code seems to want to create both the Domain Controllers.csv aswell as the Computers.csv files regardless of the OU you are currently in.
Lastly, you are using Out-File to create the CSV files where for proper CSV output, you should use the Export-Csv cmdlet.
The following code should do what you want:
$myOUArray = "OU=Domain Controllers,DC=FABRIKAM,DC=COM", "OU=Computers,DC=FABRIKAM,DC=COM"
$myFilePath = "D:\VS-Code\Powershell\AD_Computer_Management\OUs" # just the path for the output files is needed
foreach ($OU in $myOUArray) {
# determine the file name from the OU we're in
$fileName = if ($OU -match 'OU=Domain Controllers') { 'Domain Controllers.csv' } else { 'Computers.csv'}
$filePath = Join-Path -Path $myFilePath -ChildPath $fileName
Write-Host "Getting computer info from OU '$OU'"
# get a string array of the computernames found in the OU
$computers = Get-ADComputer -Filter * -SearchBase $OU -SearchScope Subtree | Select-Object -ExpandProperty Name
# loop through this array to get the properties you want for
# each computer and store that as objects in the $result variable
$result = foreach($machine in $computers){
Get-WmiObject -Class:Win32_ComputerSystem -ComputerName $machine | Select-Object -Property Name, Manufacturer, Model
}
Write-Host "Creating file '$filePath'"
# save the CSV file to disk
$result | Export-Csv -Path $filePath -NoTypeInformation -Force
}
I want to output all hostnames within a network first with a foreach loop, in order (for example) to be able to ping them.
However with the following code I do not get any output in the console. The CSV file will be saved, but what is written in the loop will not be executed.
Does anyone know what the reason for this is and how I can solve it?
Import-Module activedirectory
Get-ADComputer -Filter * -Property * | Select Name | Export-CSV -Path $env:TEMP\ZZZEXPORTE.csv -NoTypeInformation -Encoding UTF8 | ForEach {
$computerName = $_.Name
Write-Host $computerName
Write-Host "----"
}
This occurs because Export-CSV does not output an object. Sometimes cmdlets like this have a -PassThru parameter which you can use to have an object passed along, but thats not the case with Export-CSV, they simply expect it to always be the last cmdlet in the pipeline.
You should instead do this:
$Computers = Get-ADComputer -Filter * -Property * | Select Name
$Computers | Export-CSV -Path $env:TEMP\ZZZEXPORTE.csv -NoTypeInformation -Encoding UTF8
$Computers | ForEach {
$computerName = $_.Name
Write-Host $computerName
Write-Host "----"
}
You could also do this:
Get-ADComputer -Filter * -Property * | Select Name | ForEach {
$computerName = $_.Name
Write-Host $computerName
Write-Host "----"
$_
} | Export-CSV -Path $env:TEMP\ZZZEXPORTE.csv -NoTypeInformation -Encoding UTF8
Noting that we have to add $_ to our ForEach-Object loop so that it outputs the current item to the pipeline, but that our Write-Host statements don't effect the pipeline because they are writing to the console only. To be honest though, this is a bit harder to follow for anyone else reading your code.
So having some good old fashion Powershell frustrations today. What I need to do is this:
Get a list of computers from a file
Query those computers for "CSName" and "InstallDate" from Win32_OperatingSystem
Convert InstallDate into a useable date format.
Export all that to a .Csv
I've tried so many different iterations of my script. I run into 2 major issues. One is that I can't export and append to .Csv even with Export-Csv -Append. It just takes the first value and does nothing with the rest. The 2nd is that I can't get the datetime converter to work when piping |.
Here's a few samples of what I've tried - none of which work.
This sample simply errors a lot. Doesn't seem to carry $_ over from the WMI query in the pipe. It looks like it is trying to use data from the first pipe, but I'm not sure.
Get-Content -Path .\Computernames.txt | Foreach-Object {
gwmi Win32_OperatingSystem -ComputerName $_) |
Select-Object $_.CSName, $_.ConvertToDateTime($OS.InstallDate).ToShortDateString()
} | Export-Csv -Path Filename -Force -Append -NoTypeInformation
}
This one simply exports the first value and gives up on the rest when exporting .Csv
$Computers = Get-Content -Path .\Computernames.txt
foreach ($Computer in $Computers) {
echo $Computer
$OS = gwmi Win32_OperatingSystem -ComputerName $Computer
$OS | Select-Object
$OS.CSName,$OS.ConvertToDateTime($OS.InstallDate).ToShortDateString() |
Export-Csv -Path $Log.FullName -Append
}
This one does get the data, but when I try to select anything, I get null values, but I can echo just fine.
$OS = gwmi Win32_OperatingSystem -ComputerName $Computers
$OS | Foreach-Object {
Select-Object $_.CSName,$_.ConvertToDateTime($OS.InstallDate).ToShortDateString() |
Export-Csv -Path $Log.FullName -Force -Append -NoTypeInformation
}
This feels like it should be ridiculously simple. I can do this in C# with almost no effort, but I just can't get PS to do what I want. Any help would be much appreciated!
Here you go,
$Array = #() ## Create Array to hold the Data
$Computers = Get-Content -Path .\Computernames.txt
foreach ($Computer in $Computers)
{
$Result = "" | Select CSName,InstallDate ## Create Object to hold the data
$OS = Get-WmiObject Win32_OperatingSystem -ComputerName $Computer
$Result.CSName = $OS.CSName ## Add CSName to line1
$Result.InstallDate = $OS.ConvertToDateTime($OS.InstallDate).ToShortDateString() ## Add InstallDate to line2
$Array += $Result ## Add the data to the array
}
$Array = Export-Csv c:\file.csv -NoTypeInformation