Exporting Output From a Powershell Script to CSV - csv

I found a PowerShell script that looks to be just what I need, but I am having trouble exporting the output to a CSV. I think it may be the foreach portion that is giving the trouble, was wondering if anyone can pinpoint the cause.
$Groups = Get-ADGroup -Properties * -Filter * -SearchBase "OU=Groups,DC=corp,DC=ourcompany,DC=Com"
foreach ($G in $Groups)
{
Write-Host $G.Name
Write-Host "-------------"
$G.Members
}
Specific error is:
An empty pipe element is not allowed.
At line:6 char:2
+ }|Export-csv -path c:\temp\adusers.csv
+ ~
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : EmptyPipeElement

Give this one a try:
$Groups = Get-ADGroup -Properties * -Filter * -SearchBase "OU=Groups,DC=corp,DC=ourcompany,DC=Com"
$Groups | Select Name, Members | Export-Csv -Path "C:\temp\myfile.csv" -Delimiter ";"
if you want all attributes just use
$Groups | Export-Csv -Path "C:\temp\myfile.csv" -Delimiter ";"
or get your attributes as you like to:
$Groups | Select Name, Members, DistinguishedName, Email | Export-Csv -Path "C:\temp\myfile.csv" -Delimiter ";"

Related

How to call a function within a foreach parallel loop

Good evening.
I'm trying to use parallelism for the first time but I don't understand how to call a function within foreach loop.
I get a series of this error: Cannot bind argument to parameter 'Path' because it is null.
This is what I've done so far:
$FolderPath = "C:\myfolder\"
function AppendLog ($client) {
$so = New-CimSessionOption -Protocol 'DCOM'
$s = New-CimSession -ComputerName $client -SessionOption $so
Add-Content -Path (join-path $folderpath "LOGS.txt") -Value ( (get-date -Format "[yyyy.MM.dd HH:mm:ss]").tostring() + $client + " -PING: OK")
$arch = Get-CimInstance –query "select * from win32_operatingsystem" -CimSession $s | select -expandproperty osarchitecture
Add-Content -Path (join-path $folderpath "LOGS.txt") -Value ( (get-date -Format "[yyyy.MM.dd HH:mm:ss]").tostring() + $client + " -ARCH:" + $arch )
$lastboot = Get-CimInstance –query "select * from win32_operatingsystem" -CimSession $s | select -expandproperty lastbootuptime
Add-Content -Path (join-path $folderpath "LOGS.txt") -Value ( (get-date -Format "[yyyy.MM.dd HH:mm:ss]").tostring() + $client + " -BOOT:" + $lastboot )
}
$funcDef = $function:AppendLog.ToString()
$clients = get-content -path (join-path $folderPath "client.txt")
$clients | ForEach-Object -parallel {
if (test-connection $_ -count 2 -Quiet)
{
$function:AppendLog = $using:funcDef
AppendLog ($_)
}
} -throttlelimit 3
Could you explain me how to pass my path?
My bad on the comment, the error you're getting is most likely coming from your function. The error is being thrown by Join-Path:
PS /> Join-Path $null 'Logs.txt'
Join-Path : Cannot bind argument to parameter 'Path' because it is null.
At line:1 char:11
+ Join-Path $null 'Logs.txt'
+ ~~~~~
+ CategoryInfo : InvalidData: (:) [Join-Path], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.JoinPathCommand
The reason is because $FolderPath doesn't exist in the scope of your parallel loop. $folderpath should be replace with $using:folderpath inside your function.
As a side note, adding information to the same file on a parallel execution doesn't seem to be a good idea.
Last edit, I understand if this is meant to test how ForEach-Object -Parallel works but again, if the cmdlet allows remote querying / remote execution with multiple hosts at the same time, let the cmdlet handle that for you, it is more efficient.
As for the code, this is what I would use with what you already have:
$FolderPath = "C:\myfolder\"
$sessionOption = New-CimSessionOption -Protocol 'DCOM'
$clients = Get-Content -Path (Join-Path $FolderPath -ChildPath "Client.txt")
$results = $clients | ForEach-Object -Parallel {
$out = #{
Time = [datetime]::Now.ToString('[yyyy.MM.dd HH:mm:ss]')
ComputerName = $_
}
if ($ping = Test-Connection $_ -Count 2 -Quiet)
{
$session = New-CimSession -ComputerName $_ -SessionOption $using:sessionOption
$OSInfo = Get-CimInstance -CimSession $session -ClassName win32_operatingSystem
Remove-CimSession $session
}
$out.Ping = $ping
$out.Arch = $OSInfo.OSArchitecture
$out.LastBoot = $OSInfo.LastBootUpTime
[pscustomobject]$out
} -ThrottleLimit 3
$results | Export-Csv "$myFolder\LOGS.csv" -NoTypeInformation
This will output an object like this below:
Time ComputerName Ping OSArchitecture LastBoot
---- ------------ ---- -------------- --------
[2021.06.19 20:06:00] ComputerName01 True 64-bit 6/16/2021 11:47:16 AM
[2021.06.19 20:07:00] ComputerName02 False
[2021.06.19 20:08:00] ComputerName03 True 64-bit 6/13/2021 11:47:16 AM
[2021.06.19 20:09:00] ComputerName04 True 64-bit 6/14/2021 11:47:16 AM
[2021.06.19 20:10:00] ComputerName05 True 64-bit 6/15/2021 11:47:16 AM
Which can be exported nicely to a CSV instead of a text file. P.D.: sorry for the syntax highlighting :(

PowerShell failing to convert JSON to CSV

I have spent a bit of time researching how to convert Json to a CSV file using powershell but am failing to have it complete properly. Below is the syntax I have created:
$pathToOutputFile = "C:\OrderLinQ\TESTING\IN\CatalogsRetrieved\test.txt"
$pathToJsonFile = "C:\OrderLinQ\TESTING\IN\CatalogsRetrieved\test.json"
Get-Content -Path $pathToJsonFile |
ConvertFrom-Json |
ConvertTo-Csv -NoTypeInformation |
Set-Content $pathToOutputFile
However, when I attempt to execute this, I get an argument exception error:
ConvertFrom-Json : Invalid array passed in, ']' expected. (1): [
At line:1 char:69
+ Get-Content "C:\OrderLinQ\TESTING\IN\CatalogsRetrieved\test.json" | ConvertFrom- ...
+ ~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [ConvertFrom-Json], ArgumentException
+ FullyQualifiedErrorId : System.ArgumentException,Microsoft.PowerShell.Commands.ConvertFromJsonCommand
Any thoughts as to what I'm doing wrong? I've verified my file using JSONLint and it shows verified. Example file can be found at https://api.myjson.com/bins/mo59w. Any help is appreciated!
Try this. I've also attached the output
$pathToOutputFile = "D:\output.csv"
$pathToJsonFile = "D:\test.json"
$json = Get-Content -Path $pathToJsonFile
function ConvertFrom-JsonToCsv {
param(
[Parameter(ValueFromPipeline)]
$json
)
Process {
($json | ConvertFrom-Json) | ConvertTo-Csv -NoTypeInformation
}
}
ConvertFrom-JsonToCsv $json | Set-Content $pathToOutputFile
Output

Importing Bulk user CSV file

Been trying all day to import my CSV file to my AD on Windows Server 2012.
But keep getting all kind of errors.
The error I get is this:
"New-ADUser : Cannot validate argument on parameter 'Name'. The argument is null
or empty. Provide an argument that is n ot null or empty, and then try the
command again.
At line:3 char:90
+ ... ipalname -Name $_.name -DisplayName $_.name -GivenName $_.cn -SurName $_.sn -Dep ...
+ ~~~~~~~
+ CategoryInfo : InvalidData: (:) [New-ADUser], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.ActiveDirectory.Management.Commands.NewADUsery
Can't seem to find any solution to this, so some help would be great. Here is my files.
This is my script:
Import-Csv .\nb1.csv | ForEach-Object {
$userprincipalname = $_.SamAccountName + "#hirethistire.local"
New-ADUser -SamAccountName $_.SamAccountName -UserPrincipalName $userprincipalname -Name $_.name -DisplayName $_.name -GivenName $_.cn -SurName $_.sn -Department $_.Department -Path "CN_Users,DC=HireThisTire,DC=local"-AccountPassword (ConvertTo-SecureString "Microsoft~1;" -AsPlainText -force) -Enabled $true -PasswordNeverExpires $true -PassThru
}
Sample Of the CSV File:

ForEach-Object : Cannot convert 'System.Object[]'

For some reason I have a script that started to give me problems all of a sudden. Maybe a co-worker modified it, I don't know but I need to get it running again.
This is my script that is causing the problem:
$result = ForEach-Object $filter {
Select-String -Pattern $pattern |
Select-Object Path, LineNumber, Line }
$result | Export-Csv "W:\test\search_results\$name.csv" -NoType
This is what $filter contains if I export it to CSV rather than $result:
FullName
\\omega.dce-eir.net\etm\ETMWinHeadPROD\CRA_WEB_UA\cra_htdocs\bt\fq-eng.html
\\omega.dce-eir.net\etm\ETMWinHeadPROD\CRA_WEB_UA\cra_htdocs\bt\ll_fq-eng.html
\\omega.dce-eir.net\etm\ETMWinHeadPROD\CRA_WEB_UA\cra_htdocs\bt\menu-eng.html
I am getting this error when running my code:
ForEach-Object : Cannot convert 'System.Object[]' to the type 'System.Management.Automation.ScriptBlock' required by parameter 'Process'. Specified method is not supported.
At C:\Tools\menu.ps1:41 char:37
+ $result = ForEach-Object <<<< $filter {
+ CategoryInfo : InvalidArgument: (:) [ForEach-Object], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgument,Microsoft.PowerShell.Commands.ForEachObjectCommand
What am I missing in this script? All it needs to do, is a search string on the files listed in the CSV.
$filter is a list of objects, not a scriptblock. You can't use it like that with ForEach-Object. Change your code to this:
$filter | Select-Object -Expand FullName |
ForEach-Object { Select-String -Path $_ -Pattern $pattern } |
Select-Object Path, LineNumber, Line |
Export-Csv "W:\test\search_results\$name.csv" -NoType

Create a CSV with all AD users to import into Elastix

I'm working in a test environment with about 1000 users and I'm trying to create a CSV with the following headers to be used in Elastix: Display Name, User Extension, Secret, Tech.
The users currently do not have extensions assigned to them and random extensions would be fine. The secret will be "123456" for all of them. The Tech will be "Sip" for all of them.
Currently I have this, but I'm struggling to strip the name off each user in my loop:
$users = get-aduser -filter * | Select Name
$outpath = "C:\scripts\users.csv"
$outputArray =#()
"Display Name, User Extension, Secret, Tech"|out-file $outpath -Force
$ext = 1000
foreach($row in $users)
{
$outputArray += "," + $ext++ + "," + "123456" + "," + "Sip"
}
$outputArray | out-file $outpath -Force
Use can do this using the Select-Object cmdlet with 'calculated properties' and the Export-Csv cmdlet.
(Note: In my original answer I did not specify the script scope for the randomExtension variable when modified in an expression. When trying to fix, I found the solution here: How can I increase the value of a variable in an expression?
$outputPath = "C:\test\users.csv"
$script:randomExtension = 1000
get-aduser -filter * |
Select #{n='Display Name';e={$_.Name}},
#{n='User Extension';e={$script:randomExtension++; $script:randomExtension}},
#{n='Secret';e={'123456'}},
#{n='Tech';e={'Sip'}} |
Export-Csv -Path $outputPath -NoTypeInformation