Powershell Storing sqlResults into an array - mysql

I have a power shell script that querys the database and returns two columns which are a key value pair. Let's call them a & b.
How do I store this in a map to be called at a later date? Below is mysql code, it runs and prints out columns out to the screen.
$Connection = New-Object MySql.Data.MySqlClient.MySqlConnection
$Connection.ConnectionString = $ConnectionString
$Connection.Open()
$Command = New-Object MySql.Data.MySqlClient.MySqlCommand($Query, $Connection)
$DataAdapter = New-Object MySql.Data.MySqlClient.MySqlDataAdapter($Command)
$DataSet = New-Object System.Data.DataSet
$RecordCount = $dataAdapter.Fill($dataSet, "data")
$DataSet.Tables[0]
Just not sure how to store the key value pair in an mapto be used later. Both columns are numeric.
Thanks.

You want to cycle through each object in the results?
$Records = $DataSet.Tables[0]
$Records.Keys | ForEach-Object {$Record.$_}
This will allow you to iterate through the objects and run some bit of code for each of them.
For instance, I've got a hashtable like this:
$Records = [hashtable]#{'Name'='Stephen';'Hair'='Red'}
The results:
$Records.Keys | ForEach-Object {"object `$Records.$_ = $($Records.$_)"}
>object $Records.Hair = Red
>object $Records.Name = Stephen
If this isn't what you're looking for, please comment so that I can try to help you to a solution.

Related

How do I dynamically insert a string into a text file in PowerShell?

The text is an html file. The line I am interested in looks something like:
<td>INC1234</td><td>INC1235</td><td>INC1236</td>
The INC numbers are different from file to file. I'd like to parse through the line by saying something like:
if like <td>INC, then concatenate '<td><a href="https://www.website.com/=' + INC# + '>"
To give an output like:
<td><a href="https://www.website.com/=INC1234>INC1234</a></td><td><a href="https://www.website.com/=INC1235>INC1235</a></td><td><a href="https://www.website.com/=INC1236>INC1236</a></td>"
EDIT1: Ok, if I do something like:
$parse = (-split (Get-Content -Raw C:\Temp\report.txt) -match '<td>INC')
$parse
It will find the characters, but it will return the entire line rather than looking for more that match the 'INC'. Presumably because they all reside on the same line with no spaces.
EDIT2: Maybe this will help. What I'm doing is using PowerShell to write SQL commands, send it to our SQL Server, return the data and use PSWriteHTML to build the report which works fantastic. But I am wanting the first column, which is the ticket number (eg. INC1234) to be a link to the ticket it reads.
[CmdletBinding()]
Param(
[Parameter(Mandatory=$True)]
[string]$ReportName
)
## Build the query box
function Read-MultiLineInputBoxDialog([string]$Message, [string]$WindowTitle, [string]$DefaultText)
{
Add-Type -AssemblyName System.Drawing
Add-Type -AssemblyName System.Windows.Forms
## Create the Label.
$label = New-Object System.Windows.Forms.Label
$label.Location = New-Object System.Drawing.Size(10,10)
$label.Size = New-Object System.Drawing.Size(280,20)
$label.AutoSize = $true
$label.Text = $Message
## Create the TextBox used to capture the user's text.
$textBox = New-Object System.Windows.Forms.TextBox
$textBox.Location = New-Object System.Drawing.Size(10,40)
$textBox.Size = New-Object System.Drawing.Size(575,200)
$textBox.AcceptsReturn = $true
$textBox.AcceptsTab = $false
$textBox.Multiline = $true
$textBox.ScrollBars = 'Both'
$textBox.Text = $DefaultText
## Create the OK button.
$okButton = New-Object System.Windows.Forms.Button
$okButton.Location = New-Object System.Drawing.Size(415,250)
$okButton.Size = New-Object System.Drawing.Size(75,25)
$okButton.Text = "OK"
$okButton.Add_Click({ $form.Tag = $textBox.Text; $form.Close() })
## Create the Cancel button.
$cancelButton = New-Object System.Windows.Forms.Button
$cancelButton.Location = New-Object System.Drawing.Size(510,250)
$cancelButton.Size = New-Object System.Drawing.Size(75,25)
$cancelButton.Text = "Cancel"
$cancelButton.Add_Click({ $form.Tag = $null; $form.Close() })
## Create the form.
$form = New-Object System.Windows.Forms.Form
$form.Text = $WindowTitle
$form.Size = New-Object System.Drawing.Size(610,320)
$form.FormBorderStyle = 'FixedSingle'
$form.StartPosition = "CenterScreen"
$form.AutoSizeMode = 'GrowAndShrink'
$form.Topmost = $True
$form.AcceptButton = $okButton
$form.CancelButton = $cancelButton
$form.ShowInTaskbar = $true
## Add all of the controls to the form.
$form.Controls.Add($label)
$form.Controls.Add($textBox)
$form.Controls.Add($okButton)
$form.Controls.Add($cancelButton)
## Initialize and show the form.
$form.Add_Shown({$form.Activate()})
$form.ShowDialog() > $null # Trash the text of the button that was clicked.
## Return the text that the user entered.
return $form.Tag
}
## Prompt the SQL Query Box
$Query = Read-MultiLineInputBoxDialog -Message "Enter SQL Query Here" -WindowTitle "SQL Query" -DefaultText "SELECT FROM"
if ($Query -eq $null) { Break }
else { Write-Host "You entered the following text: $Query" }
## Pass query to SQL Server
$Pass = Invoke-Sqlcmd -Query $Query -ServerInstance "MY-SERVER-INSTANCE" -Username "USERNAME" -Password "PASSWORD"
## Output the report and save to the network under the specified name
New-HTML {
New-HTMLTable -EnableColumnReorder -DisableInfo -DataTable $Pass -ExcludeProperty "RowError", "RowState", "Table", `
"ItemArray", "HasErrors" -HideFooter -PagingLength 25 -SearchBuilder
New-HTMLTableStyle -FontFamily Calibri -FontSize 15 -FontStyle normal -TextAlign center -TextColor "#0a0a0a"
New-HTMLTableStyle -FontFamily Calibri -BackgroundColor "#fffdb5" -FontSize 15px -TextColor "#0a0a0a" -TextAlign center -Type RowHover
} -ShowHTML -FilePath "\\Server\$ReportName.html" -Online
The report looks something like:
Ticket: Description:
----------------------------
INC1234 Broken Monitor
INC1235 No Sound
The HTML that PSWriteHTML builds throws all of the ticket numbers on one line so I would like to edit that HTML with the <a href=""> tag to dynamically create links for each ticket # mainly because I don't know how to do it in PS and can't seem to find a good answer through Google - which is why I came here.
Although not familiar with PsWriteHtml, I guess you could simply change the Ticket properties in the array you receive in $Pass:
## Pass query to SQL Server
$Pass = Invoke-Sqlcmd -Query $Query -ServerInstance "MY-SERVER-INSTANCE" -Username "USERNAME" -Password "PASSWORD"
# convert all Tickets into hyperlinks
foreach ($item in $Pass) {
$item.Ticket = '<a href="https://www.website.com/={0}>{0}</a>'-f $item.Ticket
}
Then the rest of your code
## Output the report and save to the network under the specified name
New-HTML {...}

Convert DataTable to CSV

I want to be able to Import-Csv into a PowerShell table so I can edit each section with PowerShell script, e.g. $table.row[0].name = 100. Import-Csv doesn't give that "table" it makes with CSV file.
$tabName = "TableA"
$table = New-Object system.Data.DataTable "$tabName"
$col1 = New-Object system.Data.DataColumn ColumnName1,([string])
$col2 = New-Object system.Data.DataColumn ColumnName2,([int])
$table.columns.add($col1)
$table.columns.add($col2)
$row = $table.NewRow()
$row.ColumnName1 = "A"
$row.ColumnName2 = "1"
$table.Rows.Add($row)
$row = $table.NewRow()
$row.ColumnName1 = "B"
$row.ColumnName2 = "2"
$table.Rows.Add($row)
$table.PrimaryKey = $table.Columns[0]
$table | Export-Csv C:\test.csv
I want a way to $table | Import-Csv C:\test.csv and have the ability to $table.row[0].columnname1 = "C" and it changes "A" to "C". Then I can re-export it after making changes.
You can export a DataTable object to CSV simply by piping the table into the Export-Csv cmdlet:
$table | Export-Csv C:\table.csv -NoType
However, by doing that you lose all type information of the table columns (the Export-Csv cmdlet can only save information about the type of the objects that represent the rows, not about the type of their properties).
A better way to save and restore a DataTable object is to save the table as XML:
$writer = New-Object IO.StreamWriter 'C:\path\to\data.xml'
$table.WriteXml($writer, [Data.XmlWriteMode]::WriteSchema)
$writer.Close()
$writer.Dispose()
and restore the XML into a DataSet:
$ds = New-Object Data.DataSet
$ds.ReadXml('C:\path\to\data.xml', [Data.XmlReadMode]::ReadSchema)
$table = $ds.Tables[0]
Make sure to export and import the schema along with the data, because that's where the type information is stored.
The result of import-csv, as you found, is not a .NET DataTable object. There is this function to convert to a DataTable called "Out-DataTable" https://gallery.technet.microsoft.com/scriptcenter/4208a159-a52e-4b99-83d4-8048468d29dd . I don't know that it can go both directions, though.

Powershell, Sql and export data in loop to html

I have table in my database with following columns :
LOGIN | AVAILABLE | MORE INFO
I want to generate html's files for every unique login. Each html file should display the rows relating to a single "login". Every "login" has a different number of rows. The name of each generated file should be such as "login"
I have only a script that writes to html the entire table.
I tried to use "loop for" to generate these files, but to no avail.
This is my code:
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "ConnectionString"
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd.Connection = $SqlConnection
$SqlCmd.CommandTimeout = 0
$SqlCmd.Connection.Open()
$SqlCmd.CommandText = "select login, available, more_info from [schema].[table]"
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter.SelectCommand = $SqlCmd
$DataSet = New-Object System.Data.DataSet
$SqlAdapter.Fill($DataSet)
$FilePath = "Path" + login + ".html"
$Title = " Title"
$DataSet.Tables[0] | convertto-html -property login, available, more_info -title $Title > $FilePath

Powershell SQL query result not fitting

Hi I have constructed a script that works fine except for one thing, sometimes the returned string is so long that it doesnt fit in the powershell console and when I later on send the text to a richtextbox I get all the ....... at the end and not the whole string
$username = "myaccount"
$sqlconnection = New-Object system.data.sqlclient.sqlconnection
$sqlconnection.ConnectionString ="server=myserver\sccm;database=sccm;trusted_connection=true;"
$sqlconnection.Open()
sqlcmd = New-Object system.data.sqlclient.sqlcommand
$sqlcmd = $sqlconnection.CreateCommand()
$sqlcmd.CommandText = "SELECT Info from SCCM.dbo.log WHERE Username = '$username'"
$sqlcmd.Connection = $sqlconnection
$data = New-Object system.data.sqlclient.sqldataadapter $sqlcmd
$dataset = New-Object system.data.dataset
$data.Fill($dataset)
$global:result = $dataset.Tables
I cannot specify the -Width parameter anywhere so I am lost on how to get the full length of the result?
Rather than display in powershell, you could save the dataset as a csv file:
#Fill the dataset with the SQL response. Using [void] redirects console output to null (don't display)
[void]$data.Fill($dataset)
#Pipe the contents of the dataset. Use Select to select all columns/properties excluding those that were created by the DataSet object (not actual data)
#Pipe to Export-CSV to create a CSV file, use -notypeinformation flag to skip Object type information from the file (e.g. System.String etc)
$dataset.Tables[0] | Select * -ExcludeProperty RowError, RowState, HasErrors, Table, ItemArray | Export-CSV -notypeinformation -path C:\Somedir\Somefile.csv

Utilizing MySQL query results

Need help with solving this problem:
I need to get table data from MySQL DB for further use in script. I'm using this code for accessing MySQL data:
[void][System.Reflection.Assembly]::LoadFrom("C:\Program Files (x86)\MySQL\MySQL Connector Net 6.7.4\Assemblies\v2.0\MySql.Data.dll")
$Connection = New-Object MySql.Data.MySqlClient.MySqlConnection
$Connection.ConnectionString = $ConnectionString
$Connection.Open()
$Command = New-Object MySql.Data.MySqlClient.MySqlCommand($Query, $Connection)
$DataAdapter = New-Object MySql.Data.MySqlClient.MySqlDataAdapter($Command)
$DataSet = New-Object System.Data.DataSet
$RecordCount = $dataAdapter.Fill($dataSet,"data") | Out-Null
$Command.Dispose()
$Table=$DataSet.Tables["data"] | FT -auto
$Connection.Close()
$Table
and it gives me my precious piece of junk:
TASKID TASKTYPE fistNAME secNAME STATUS
------ -------- -------- ------- ------
1111 1 Dep1 0
2222 2 User321 Dep1 0
BUT when I try to, for example export results to CSV:
Export-Csv -Path "c:\test.csv" -InputObject $Table
all I get is:
#TYPE System.Object[]
"Count","Length","LongLength","Rank","SyncRoot","IsReadOnly","IsFixedSize","IsSynchronized"
"6","6","6","1","System.Object[]","False","True","False"
so when I try to parse data in variable like this:
Write-Host $Table
foreach ($Task in $Table) {
Write-Host $Task.TASKID
}
all I get is:
Microsoft.PowerShell.Commands.Internal.Format.FormatStartData
Microsoft.PowerShell.Commands.Internal.Format.GroupStartData
Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData
Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData
Microsoft.PowerShell.Commands.Internal.Format.GroupEndData
Microsoft.PowerShell.Commands.Internal.Format.FormatEndData
Can anyone help me to resove this problem?
This line
$Table=$DataSet.Tables["data"] | FT -auto
transforms your data into an array of FormatStartData objects.
Don't pipe your data into Format-Table when you want to export it. Try this instead:
$DataSet.Tables["data"] | Export-Csv "c:\test.csv"