I'm running into a small issue trying to get the output from a stored procedure into a text file via. Powershell.
#Connection Object
$cn = New-Object System.Data.SqlClient.SqlConnection(
"Data Source=localhost; Database=test;User ID=test;Password=xyzzy;"
)
$q = "exec usp_Users"
#Data Adapter which will gather the data using our query
$da = New-Object System.Data.SqlClient.SqlDataAdapter($q, $cn)
#DataSet which will hold the data we have gathered
$ds = New-Object System.Data.DataSet
#Out-Null is used so the number of affected rows isn't printed
$da.Fill($ds) >$null| Out-Null
#Close the database connection
$cn.Close()
if($ds.Tables[0].Rows.Count -eq 0){
write-host '0:No Data found'
exit 2
}
$file = "C:\temp\" + "users" + $(Get-Date -Format 'MM_dd_yyyy') + ".txt"
$ds.Tables[0] | out-File $file -encoding ASCII -width 255
Here is the output:
Column1
-----
USER_NAME,USER_TYPE
test#spamex.com,MasterAdministrator
foo#hotmail.com,UserAdministrator
test4#test.com,Users
How can I get rid of the 'Column1' and the underline?
select-object with expanded property might help:
ds.Tables[0] | Select-Object -expand Column1 | out-file..
You can export a datatable directly into a csv file by using export-csv:
$ds.Tables[0] | export-csv tofile.csv -notypeinformation
Related
I want to extract text from a .txt file. The way the file is layed out is in this format (below first block). Optimally, I would like for the powershell script to take the content of username and votecount and output them side by side. With an integer of 25>= add the letter D beside it. With the output adding itself to a pre-existing output file. Say this week is week 1. And testuser voted 25 times. They should have the output "testuser" 25D. But say in week 2 they voted 24 times. Then it should be "testuser" 49D. However say they had 25 again. Output should then be "testuser" 50DD or 50D2?.. I have what I think should work as an initial baseline for the script which in itself doesn't work.. But combining an output with a pre existing output is beyond my capability. This needs to parse an entire txt file of some 100+ people. So imagine there's like an extra 100 users..
{
"username": "testuser",
"votecount": "42",
"votesclaimed": "0",
"lastvotetime": "2022-11-04 09:08:29",
"steamid": "00000000000000000000"
}
Below is what I am working with.
Get-Content -Raw C:\Users\--------\Desktop\votes.txt |
ConvertFrom-txt |
ForEach-Object {
[pscustomobject] #{
UserName = $_.username
VoteCount = '{0}{1}' -f $_.votecount, ('', 'D')[[int] $_.votecount -gt 25]
}
} |
Export-Csv -NoTypeInformation -Encoding utf8 C:\Users\---------\Desktop\outvotes.csv
Try following :
$match = Select-String -Path "c:\temp\test.txt" -Pattern '^\s*"(?<key>[^"]+)"\s*:\s*"(?<value>[^"]+)'
$table = [System.Collections.ArrayList]::new()
foreach( $row in $match.Matches )
{
$key = $row.Groups["key"].Value
$value = $row.Groups["value"].Value
if($key -eq "username") {
$newRow = New-Object -TypeName psobject
$table.Add($newRow) | Out-Null
}
$newRow | Add-Member -NotePropertyName $key -NotePropertyValue $value
}
$table | Format-Table
$groups = $table | Group-Object {$_.username}
I have a CSV with a lot of headers. It ranges from Column A to AZ. I need to read only the first column of the CSV.
My issue is the last column (comments) bleeds into the first column when opened in notepad++ and it appears to show that it is apart of Column one (host name). When I run my code it reads it as notepad++ does.
I originally convert this from an .xls to a CSV file, is there a way to ensure the last column does not wrap around?
#region - Convert to CVS
$strFileName = "C:\working\Server Count & Status Check ARC 0219183.xlsx"
$strSheetName = 'SCI$'
$strProvider = "Provider=Microsoft.ACE.OLEDB.12.0"
$strDataSource = "Data Source = $strFileName"
$strExtend = "Extended Properties='Excel 8.0;HDR=Yes;IMEX=1';"
$strQuery = "Select * from [$strSheetName]"
$objConn = New-Object
System.Data.OleDb.OleDbConnection("$strProvider;$strDataSource;$strExtend")
$sqlCommand = New-Object System.Data.OleDb.OleDbCommand($strQuery)
$sqlCommand.Connection = $objConn
$objConn.open()
$da = New-Object system.Data.OleDb.OleDbDataAdapter($sqlCommand)
$dt = New-Object system.Data.datatable
$da.fill($dt)
$dt | Export-Csv "C:\working\Server Count & Status Check ARC 0219183.csv" -
NoTypeInformation
$objConn.close()
#endregion
Original Spreadsheet
After trying to gather first column(hostname)
$array=#{}
$ServerStatus = Get-Content "C:\Users\user\Desktop\Scripts\Linux Server
Compare\Server Count & Status Check ARC 0219183.csv" | select -skip 1 |
ConvertFrom-Csv -Header "HostName","Business Application","Technical
Function","Location","Environment","Day Number","Slot
Number","SlotTime","Description","DNS Name","Key Server","Host Name","Public
IP","Server Type","Build Date","Builder","Product Name","Serial
No","Enclosure","Bay","CPU Model","CPU Socket","CPU Cores","Logical
CPU","Memory","Up Time","Kernel Version","OS Type","Version","Patch
level","Multipath Disks?","Multipath Checker?","Customized Fsck?","Splx
Installed?","Splx Running?","Suse Manager Status","RHN Running ?","RHN
Autostart?","Installed Kernel","Available Kernel in
/boot","Hardened","Syslog
Config correct ?","Syslog Running ?","Patrol Running?","Splunk
Installed?","Splunk Running?","Puppet Installed?","Puppet
Running?","Centrify
Version","VM Tools Installed?","VM Tools Running?","Comments"
$ServerStatusObj = new-object Object
$ServerStatusObj | add-member -membertype NoteProperty "Name" -value ""
$ServerStatusObj | add-member -membertype NoteProperty "Origin" -value ""
$array=#{name = $ServerStatus.HostName}
foreach ($name in $array.name){
if($name -ne $null){
$Value = $name
if($name -ne $null){
$ServerStatusObj.name =$Value
$ServerStatusObj.Origin = " Linux Servers"
} #End of IF
else {Write-Output "null"}
Write-Output $ServerStatusObj | export-csv
"C:\Users\user\Desktop\Scripts\Linux Server Compare\ServerStatusParse.csv" -notypeinformation -Append
}
I'm quite new to powershell and struggling with outputting data to a CSV file.
I have a larger code piece but created the below small working example that contains the issue:
$results = #()
$tmp_avs = #('tmp', 'tmp2')
$hostname = 'hostname'
$results += New-Object -TypeName PSObject -Property (#{Hostname=$hostname; avs=$tmp_avs})
$res = $results | ? {$_.avs.Count -gt 0} | Format-Table
$res | Export-Csv -NoTypeInformation "test.csv"
When printing the $res object above in PowerShell I get the output:
avs Hostname
--- --------
{tmp, tmp2} hostname
That is also the output I would like to receive in the CSV file, but currently I get something like this:
"ClassId2e4f51ef21dd47e99d3c952918aff9cd","pageHeaderEntry","pageFooterEntry","autosizeInfo","shapeInfo","groupingEntry"
"033ecb2bc07a4d43b5ef94ed5a35d280",,,,"Microsoft.PowerShell.Commands.Internal.Format.TableHeaderInfo",
"9e210fe47d09416682b841769c78b8a3",,,,,
"27c87ef9bbda4f709f6b4002fa4af63c",,,,,
"4ec4f0187cb04f4cb6973460dfe252df",,,,,
"cf522b78d86c486691226b40aa69e95c",,,,,
Is there a possibility to export the $res object in a proper CSV format?
EDIT:
I removed the Format-Table now, which results in the following in the CSV format:
"avs","Hostname"
"System.Object[]","hostname"
There is System.Object[] written instead of the values?
The values are an array. If you run $tmp_avs.ToString(), you will also get System.Object[]
To resolve, replace avs=$tmp_avs with avs=$($tmp_avs -join " ") where is the joining character between elements of your array. It converts the array to a string.
Code:
$results = #()
$tmp_avs = #('tmp', 'tmp2')
$hostname = 'hostname'
$results = New-Object -TypeName PSObject -Property (#{Hostname=$hostname; avs=$($tmp_avs -join " ")})
$res = $results | ? {$_.avs.Count -gt 0}
$res | Export-Csv -NoTypeInformation "test.csv"
Output:
avs,Hostname
tmp tmp2, hostname
If you do not want to see System.object[], but a comma separated list, you could convert your array to a string, so this can be outputted correctly in CSV.
Try adding $tmp_avs = $tmp_avs -join ";" to your script below the line $tmp_avs = #('tmp', 'tmp2').
I'm trying to run a query in WSUS API via Powershell that outputs computer names, needed patches, etc, and then I need to inject that into a "log" file which gets ingested into Splunk so we can make dashboards etc.
My current code is
$computerscope = New-Object Microsoft.UpdateServices.Administration.ComputerTargetScope
$LogTime = Get-Date -Format "MM-dd-yyyy_hh-mm-ss"
$updatescope = New-Object Microsoft.UpdateServices.Administration.UpdateScope
$wsus.GetSummariesPerComputerTarget($updatescope,$computerscope) |
Select-Object $logtime,#{L=’ComputerTarget';E={($wsus.GetComputerTarget([guid]$_.ComputerTargetId)).FullDomainName}},
#{L=’NeededCount';E={($_.DownloadedCount + $_.NotInstalledCount)}},DownloadedCount,NotApplicableCount,NotInstalledCount,InstalledCount,FailedCount | Select-String Computer
Output comes out like this:
#{05-13-2016_05-12-25=; ComputerTarget=########; NeededCount=12; DownloadedCount=0; NotApplicableCount=82245; NotInstalledCount=12; InstalledCount=23; FailedCount=0}
I need it to look like this:
05-13-2016_05-12-25=; ComputerTarget=#######; NeededCount=12; DownloadedCount=0; NotApplicableCount=82245; NotInstalledCount=12; InstalledCount=23; FailedCount=0
If you want to try the root of the problem, I'm trying to convert a table into arrays so splunk can read it line by line but this gives a table which i'm trying to convert:
$computerscope = New-Object Microsoft.UpdateServices.Administration.ComputerTargetScope
$LogTime = Get-Date -Format "MM-dd-yyyy_hh-mm-ss"
$updatescope = New-Object Microsoft.UpdateServices.Administration.UpdateScope
$wsus.GetSummariesPerComputerTarget($updatescope,$computerscope) |
Select-Object $logtime,#{L=’ComputerTarget';E={($wsus.GetComputerTarget([guid]$_.ComputerTargetId)).FullDomainName}},
#{L=’NeededCount';E={($_.DownloadedCount + $_.NotInstalledCount)}},DownloadedCount,NotApplicableCount,NotInstalledCount,InstalledCount,FailedCount `
which gives output:
05-13-2016_05-16-04 :
ComputerTarget : ########
NeededCount : 12
DownloadedCount : 0
NotApplicableCount : 82245
NotInstalledCount : 12
InstalledCount : 23
FailedCount : 0
It looks like you only want to remove the leading #{ and trailing } which you could do with regex like this:
...allyourcode... | Select-String Computer | ForEach-Object { $_.Line -replace '^\#\{(.*?)\}$', '$1' }
However, making Select-String convert your objects to string-representations is a bad way to export data. Splunk can read CSV-files, so I would recommend using that (and also use a real property for logtime). Ex:
$computerscope = New-Object Microsoft.UpdateServices.Administration.ComputerTargetScope
$LogTime = Get-Date -Format "MM-dd-yyyy_hh-mm-ss"
$updatescope = New-Object Microsoft.UpdateServices.Administration.UpdateScope
$wsus.GetSummariesPerComputerTarget($updatescope,$computerscope) |
Select-Object #{L="LogTime";e={ $logtime }},#{L=’ComputerTarget';E={($wsus.GetComputerTarget([guid]$_.ComputerTargetId)).FullDomainName}},
#{L=’NeededCount';E={($_.DownloadedCount + $_.NotInstalledCount)}},DownloadedCount,NotApplicableCount,NotInstalledCount,InstalledCount,FailedCount |
Export-Csv -Path mydata.csv -NoTypeInformation
I have a text file(with header Actual_Output and saved it as actual.txt) containing data such as
Actual_Output
W
à
é
"
'
(
_
ç
²"
^
^
*
END
I want to convert it into csv file using powershell. I doing in this way
$DB = import-csv E:\actual.txt
$outarray = #()
foreach ($Data in $DB)
{
$First = $Data.Actual_Output
$outarray += New-Object PsObject -property #{
'Actual_Output' = $First
}
write-host "Actual_Output: " $First
write-Host ""
}
$outarray | export-csv 'E:\result.csv' -NoTypeInformation -Encoding utf8
I am getting the output like this as shown in screenshot
I want each data to be listed in seperate cell. Actually double quote " is creating problem here. Please help in resolving this. Sorry if i am unclear in describing the issue
Tested this, and it seems to work better:
Get-Content actual.txt | select -Skip 1 |
foreach {
New-Object PSObject -Property #{Actual_Output = $_}
} | export-csv result.csv -NoTypeInformation -Encoding UTF8
The file isn't well-formed as CSV initially, so Import-CSV isn't able to parse it correctly.