Powershell - Separate output based on Server + export to Excel - powershell

Running a sql script for a list of databases.
The output on powershell is not separated. How could I separate them based on server name.
$SERVERS = gc "C:\Users\listOfServers.txt"
foreach ($SERVER in $SERVERS) {
$InvokeParams = #{
Server = $SERVER
Database = 'test'
Username = 'admin'
Password = 'testpassword'
InputFile = 'C:\business.sql'
}
Invoke-SqlCmd #InvokeParams
}
Right now my output looks like this :
ValueDate: 1/30/2019 12:00:00 AM
PrevValueDate: 1/29/2019 12:00:00 AM
Count:100
ValueDate: 3/30/2019 12:00:00 AM
PrevValueDate: 3/29/2019 12:00:00 AM
Count:200
ValueDate: 4/30/2019 12:00:00 AM
PrevValueDate: 4/29/2019 12:00:00 AM
Count:2100
ValueDate: 11/30/2019 12:00:00 AM
PrevValueDate: 11/29/2019 12:00:00 AM
Count:12200
Goal is : Server 1 (output server 1) server 2 (output server 2)
I would like to add a parameter that gives the server name for each output- or sort like an Id to separate them.
Goal is to export the output into an Excel sheet - not working at the moment
$out = Invoke-SqlCmd #InvokeParams | Format-Table
$path = 'C:\Users\test1.csv'
$out | Export-Csv -Path $path
Invoke-Item -Path $path

You can use calculated properties to achieve this:
$SERVERS = gc "C:\Users\listOfServers.txt"
$out = foreach ($SERVER in $SERVERS) {
$InvokeParams = #{
Server = $SERVER
Database = 'test'
Username = 'admin'
Password = 'testpassword'
InputFile = 'C:\business.sql'
}
Invoke-SqlCmd #InvokeParams | Select-Object -Property *, #{L='Server'; E={$SERVER}}
}
$path = 'C:\Users\test1.csv'
$out | Export-Csv -Path $path
Invoke-Item -Path $path

Related

Trying to extract specific text and merge output with existing output

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}

Powershell Script to parse selected information from txt file and output to csv

checked the FAQ's on parsing data and have tried a couple ideas but nothing is working the way I need it. I need a suggestion on how to build a PS script that will read the following information in my .txt file and output only selected information to .csv
eamoptns.ftr.0009: LoyaltyPrint3 = " included with your TV purchase"
eamoptns.ftr.0010: LoyaltyPrint3 = " included with your TV purchase"
Grand Total: 2 match(es) found.
CSV file will contain three columns:
Store Install Date
Need PS script to grab the store # (0009) and add it under the Store column. If that line contains "included with your TV purchase" under the install column add True if not add False and then add the date in date column.
Code try from comment
$PSRoot = Split-Path -Parent -Path $MyInvocation.MyCommand.Definition
Get-ChildItem $PSRoot -Filter "*Results.txt" |
Where-Object { $_.Attributes -ne "Directory" } | ForEach-Object {
If (Get-Content $_.FullName | Select-String -Pattern "included with your TV purchase") {
New-Object -TypeName PSCustomObject -Property #{
Club = $A
Install = $B
Date = $C
} | Export-CSV -Path $PSRoot\Test.csv -Append
}
}
As suggested
choose a regular expression that matches your requrements (see regex101.com)
iterate the matches and compare the ,matched text
generate a [PSCustomObject] for your csv
## Q:\Test\2018\10\17\SO_52857274.ps1
$RE = [RegEx]'^.*?\.(\d{4}):[^"]+"\s*(included with your TV purchase|.*)"$'
$CSV = Select-String '.\my.txt' -Pattern $RE | ForEach-Object {
IF ($_.Matches.Groups[2].Value -eq 'included with your TV purchase'){
$Install = $True
} else {
$Install = $False
}
[PSCustomObject]#{
Store = $_.Matches.Groups[1].Value
Install = $Install
Date = (Get-Date).Date
}
}
$CSV
# $CSV | Export-CSV '.\my.csv' -NoTypeInformation
Sample output:
> Q:\Test\2018\10\17\SO_52857274.ps1
Store Install Date
----- ------- ----
0009 True 2018-10-17 00:00:00
0010 True 2018-10-17 00:00:00
0010 False 2018-10-17 00:00:00

Powershell Convert Table To Array

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

Formatting Powershell output from stored procedure

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

How to put a header to csv file generated by Powershell script

I got this Powershell script that queries users that have not changed their password for 24 hours. The query redirects the output to csv file. Below are the Powershell script and batch script:
Powershell script:
$root = [ADSI]''
$searcher = new-object System.DirectoryServices.DirectorySearcher($root)
$searcher.filter = "(&(objectCategory=person)(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2)))"
$searcher.sizelimit = 5000
[Void]$searcher.PropertiesToLoad.Add("cn")
[Void]$searcher.PropertiesToLoad.Add("samAccountName")
[Void]$searcher.PropertiesToLoad.Add("pwdLastSet")
$users = $searcher.findall()
$UserOU = "OU=Mountain,DC=Atlanta,DC=ga"
$PWDays = (Get-Date).AddDays(-1)
$UserCount = 0
$UserPW = 0
foreach($user in $users)
{
if ($user.path -like "*$UserOU")
{
$usercount = $UserCount
if ([datetime]::FromFileTime(($user.properties.pwdlastset)[0]) -le $PWDays)
{
$UserPW = $UserPW + 1
Write-Host $user.Properties.cn
}
}
}
Batch script:
powershell.exe d:\temp\query.ps1 > D:\temp\query.csv
My question is: How do I put change the script to put header for username in the the csv output file?
The header may simple be 'Username' not necessarily Firstname and Lastname.
Any reason why you aren't using Export-Csv? You can just pipe your objects into it and it will include headers. Something along the lines of
$users |
? { $_.Path -like "*$UserOU" } |
? { [datetime]::FromFileTime(($user.properties.pwdlastset)[0]) -le $PWDays } |
% { $_ | Add-Member -PassThru NoteProperty Username $_.Properties.cn } |
select Username |
Export-Csv D:\temp\query.csv
might work. (Hint: The pipeline is more fun than the loop :))
Not sure (never have user PS) but I guess that sticking
Write-Host "Username"
before the foreach, might do the trick