Unable to export my data to a CSV - powershell

I have some data I am trying to push out to a CSV but it keeps failing. Any advice?
Import-Module ActiveDirectory
$ExportFile = "C:\T2\Test.csv"
$MacHeading = "Mac OS: "
$MACOS = Get-ADComputer -Filter 'OperatingSystem -like "MAC*"' -Properties OperatingSystem, CanonicalName | Select Name, CanonicalName, OperatingSystem
$MACOSCount = Get-ADComputer -Filter 'OperatingSystem -like "MAC*"' | Measure-Object | %{$_.Count}
$MacHeading | Export-CSV -path $ExportFile -Append
$MACOS | Export-CSV -path $ExportFile -Append
$MACOSCount | Export-CSV -path $ExportFile -Append
My error message is:
Export-CSV : Cannot append CSV content to the following file:
C:\T2\Test.csv. The appended object does not have a property that
corresponds to the following column: Mac OS: . To continue with
mismatched properties, add the -Force parameter, and then retry the
command. At C:\T2\Test.ps1:9 char:15
+ $MacHeading | Export-CSV -path $ExportFile -Append
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (Mac OS: :String) [Export-Csv], InvalidOperationException
+ FullyQualifiedErrorId : CannotAppendCsvWithMismatchedPropertyNames,Microsoft.PowerShell.Commands.ExportCsvCommand

while you can create a csv file manually it is usually cumbersome and you will have to match the column headers when you add data manually.
In your code above you start your csv by creating a csv file with one header\column 'mac os'. macos is an objects with various properties and it does not contain a header called 'mac os' so export-csv does not know where to send the data.
also you are missing the -notypeinformation switch to export-csv without which the csv will contain an additional unneeded header with object type
you can look at doing something like this:
$comps = Get-ADComputer -Filter 'OperatingSystem -like "MAC*"' -Properties OperatingSystem, CanonicalName |
Select-Object #{N='MacHeading';e={'Mac OS'}},Name, CanonicalName, OperatingSystem
$comps |
ForEach-Object -Begin {$i = 0} -Process {$I++; $_ | Add-Member -Name ID -Value $i -MemberType NoteProperty -PassThru} |
Export-Csv -Path $path -NoTypeInformation

$comps=Get-ADComputer -Filter { OperatingSystem -Like '*MAC*' } -Properties OperatingSystem,CanonicalName

If you're willing to go without the $MacHeading (which isn't terribly useful for a CSV), you could just do this:
Get-ADComputer -Filter 'OperatingSystem -like "MAC*"' -Properties OperatingSystem, CanonicalName |
Select Name, CanonicalName, OperatingSystem |
Export-CSV -path $ExportFile -Append -NoTypeInformation
Get-ADComputer -Filter 'OperatingSystem -like "MAC*"' |
Measure-Object | %{$_.Count} |
Out-File $ExportFile -Append -Encoding ASCII
The key is to use Out-File instead of Out-CSV for the items that won't really make a CSV.

Related

Powershell script Get-AdComputer

Import-CSV -Path C:\Users\*******\Desktop\Powershell\Input.csv |
ForEach {
Get-ADComputer -identity $_.computer -properties * |
select CN, extensionAttribute1, created, Description, DistinguishedName, enabled
} |
export-csv -path C:\Users\*******\Desktop\Powershell\Output.csv -Append -Encoding UTF8 -Delimiter ";"
Hi, how i can change my PS script.
If user from CSV not found then paste NAME;"NOT_FOUND", now my script just skip users that were not found with errors.
What you could do is a try/catch block, so that if an error occurs (when it does not exists) it outputs not found for the value "CN".
Import-CSV -Path C:\Users\*******\Desktop\Powershell\Input.csv | ForEach {
$computer = $_.computer
try{
Get-ADComputer -identity $computer -properties *
}catch{
#{
CN = "$computer not found"
}
}
} | select #{n="CN";e={$_.CN}}, extensionAttribute1, created, Description, DistinguishedName, enabled | Export-Csv -path C:\Users\*******\Desktop\Powershell\Output.csv -Append -Encoding UTF8 -Delimiter ";"
Or as your less readable one-liner:
Import-CSV -Path C:\Users\*******\Desktop\Powershell\Input.csv | ForEach {try{Get-ADComputer -identity $_.computer -properties *}catch{#{CN = "Not found"}}} | select #{n="CN";e={$_.CN}}, extensionAttribute1, created, Description, DistinguishedName, enabled | export-csv -path C:\Users\*******\Desktop\Powershell\Output.csv -Append -Encoding UTF8 -Delimiter ";"
Note that at the select we use an expression. It says name (n)="CN";expression (e)=$_.CN which is the CN and in case of an error it consists of the value "not found" from the catch block. You can also choose to add this expression to more/different values of the select statement if you enrich the object at the catch block. Or use if/else in the expression.

Export groups and username of a user in Active Directory

I am trying to find out the Active Directory groups all our active users are in and want to export it to a CSV file. However the following command presents garbage in the related CSV file.
This is my code failing:
Import-Module ActiveDirectory
Get-ADUser -SearchBase "CN=Users,DC=Mycompany,DC=de" -Filter * | where { $_.enabled -eq "true" } | foreach-object {
write-host "User:" $_.Name
Get-ADPrincipalGroupMembership $_.SamAccountName | foreach-object {
write-host "Member of:" $_.name | export-csv "C:\scripts\output\ad-user-with-group-memberhip.csv" -NoTypeInformation -Encoding UTF8
}
}
Any idea what am I doing wrong here?
Write-Host only writes text to the console window. It doesn't output anything useful to pipe through to Export-Csv.
Also, unless you add switch -Append, you should set the Export-Csv cmdlet as last line in the code, otherwise you will overwrite it in every iteration.
Try
with Select-Object
Import-Module ActiveDirectory
Get-ADUser -SearchBase "CN=Users,DC=Mycompany,DC=de" -Filter "Enabled -eq $true" |
Select-Object Name, #{Name = 'Groups'; Expression = {($_ | Get-ADPrincipalGroupMembership).Name -join '; '}} |
Export-Csv -Path "C:\scripts\output\ad-user-with-group-memberhip.csv" -NoTypeInformation -Encoding UTF8
or with ForEach-Object
Import-Module ActiveDirectory
$result = Get-ADUser -SearchBase "CN=Users,DC=Mycompany,DC=de" -Filter "Enabled -eq $true" |
ForEach-Object {
[PsCustomObject]#{
Name = $_.Name
Groups = ($_ | Get-ADPrincipalGroupMembership).Name -join '; '
}
}
$result | Export-Csv -Path "C:\scripts\output\ad-user-with-group-memberhip.csv" -NoTypeInformation -Encoding UTF8

Output Powershell Domain Search on separate excel sheets

I'm executing a Get-ADComputer and trying to iterate through a loop that pulls computer names from individual rooms. I'm trying to output each room to a different Excel sheet.
I'm running PowerShell Version 5:
$results = for($room=102; $room -le 110; $room++) {
Get-ADComputer -SearchBase $oubase -Properties Name, Description -Filter * |
Where-Object {$_.description -clike "*RM $Room"}
}
$results |
Select-Object Name, Description |
Export-CSV '\\Desktop\Room_Hosts.csv' -NoTypeInformation -Encoding UTF8 -Append
What do I need to do to fix the Excel sheet output?
Your post says you want an Excel sheet, but your code is outputting to a CSV. You cannot add a second sheet to a CSV. You can export different CSV files per computer object.
$results = for($room=102; $room -le 110; $room++) {
Get-ADComputer -SearchBase $oubase -Properties Name, Description -Filter * |
Where-Object {$_.description -clike "*RM $Room"}
}
$results |
Select-Object Name, Description | Foreach-Object {
$_ | Export-CSV -Path ("\\Desktop\{0}.csv" -f $_.Name) -NoTypeInformation -Encoding UTF8 -Append
If the problem is getting the domain name, you can add some code to your Select-Object command.
$results = for($room=102; $room -le 110; $room++) {
Get-ADComputer -SearchBase $oubase -Properties Name,Description,DNSHostName -Filter * |
Where-Object {$_.description -clike "*RM $Room"}
}
$results |
Select-Object Name,Description,#{n='Domain';e={$_.DNSHostName -Replace $("{0}." -f $_.Name}} |
Export-CSV '\\Desktop\Room_Hosts.csv' -NoTypeInformation -Encoding UTF8 -Append
Explanation For Retrieving Computer Object's Domain:
The DNSHostName property contains the FQDN of the computer object. So you only need to remove the host name part of that string. Here, we simply replace the hostname and the following . character with nothing. Hostname is retrieved from the Name property of the computer object. The -f operator is used to simply append the . character to the name. The Select-Object uses a hash table to calculate the domain value and store it in a property called Domain.
Alternatively, you can apply the same concepts from above for getting the domain name but use the CanonicalName of the computer object with the -Split operator.
$results = for($room=102; $room -le 110; $room++) {
Get-ADComputer -SearchBase $oubase -Properties Name,CanonicalName,Description -Filter * |
Where-Object {$_.description -clike "*RM $Room"}
}
$results |
Select-Object Name,Description,#{n='Domain';e={($_.CanonicalName -Split "/")[0]}} |
Export-CSV '\\Desktop\Room_Hosts.csv' -NoTypeInformation -Encoding UTF8 -Append

How to set Get-ADComputer result as object

I have this Powershell command:
Get-ADComputer -filter { Name -like 'srv*' } | Select -Expand dnshostname | Export-CSV -path ad_export.csv
In the CSV it only writes the length of the Strings. I read that I have to pipe an object to Export-CSV so it writes the Servernames and not only the length. How do I do that?
Based on the requirement , you can use :
Get-ADComputer -Filter 'ObjectClass -eq "Computer"' | Select -Expand DNSHostName | Export-CSV -path ad_export.csv
# Getting just the hostname
Get-ADComputer -Filter * | Select -Expand Name | Export-CSV -path ad_export.csv
# Getting a specific computer
Get-ADComputer -Filter { Name -eq 'server2012' } -Propert LastLogonTimestamp | Select DistinguishedName, LastLogonTimestamp | Format-Table -AutoSize | Export-CSV -path ad_export.csv
Note: You can use the "where" clause also if required.
Hope This suffice your need

New-Item : Access to the path is denied

I have a PowerShell script below
$ous = 'ou=office,dc=xxx,dc=com',`
'ou=shop0,dc=xxx,dc=com',`
'ou=shop1,dc=xxx,dc=com',`
'ou=shop2,dc=xxx,dc=com'
$outfile = 'c:\work\userinfo.csv'
New-Item -Force -type "file" -Path 'c:\work\userinfo.csv'
$ous | ForEach {
Get-ADUser -Filter * -SearchBase $_ |
Select-Object -Property CN,`
DisplayName,`
GivenName,`
Surname,`
SamAccountName,`
PasswordExpired,`
mail,`
Description,`
Office,`
EmployeeNumber,`
Title |
Sort-Object -Property Name |
export-csv -Append $outfile -NoTypeInformation
}
Then when I run it, I got error message "New-Item: access to the path c:\work\userinfo.csv" is denied.
What's the cause for this error?
Update:
In my case, somehow, PowerShell is case-sensitive....the output folder name is uppercase, in my script is lowercase, it works after I match them.
I am bypassing the reason for the error ( of which I'm not sure of the cause.). Another way to get what you want
each time I run script, I could get an fresh result without previous results
You just need to move the output code outside the loop and remove the append. Pipeline handles the Append for you.
$ous | ForEach {
Get-ADUser -Filter * -SearchBase $_ |
Select-Object -Property CN,`
DisplayName,`
GivenName,`
Surname,`
SamAccountName,`
PasswordExpired,`
mail,`
Description,`
Office,`
EmployeeNumber,`
Title
} | Sort-Object -Property Name |
export-csv -Append $outfile -NoTypeInformation
Noticed something
You are not calling all the properties you are using in your select statement. That should lead to some null columns in your output. I would update your code to something like this.
$props = "CN","DisplayName","GivenName","Surname","SamAccountName","PasswordExpired","mail","Description","Office","EmployeeNumber","Title"
$ous | ForEach-Object {
Get-ADUser -Filter * -SearchBase $_ -Properties $props | Select-Object $props
} | Sort-Object -Property Name |
export-csv $outfile -NoTypeInformation