sql command in powershell script - sql

Thanks in advance for taking the time to review this problem I have.
I am trying to streamline a process which uploads UPS tracking numbers into our ERP system. Basically, I am trying to merge all processes into a single powershell script. I am getting hung up on the sql portion to update our ERP. The sql code in itself works when run via SQL management studio as it is part of our current procedure, but when embedded in powershell, it bugs out.
Here is the basic logic:
massage 4 csv files (one for each warehouse we ship from)
execute 4 sql queries
In my code, I massage the 4 files which works and for testing I made several test queries just to see if sql connectivity is working. You will see select statements which actually return data.
Error:
**The 'from' keyword is not supported in this version of the language.
At C:\Users\dallan\desktop\sqltest3.ps1:56 char:8
+ FROM <<<< 'D:`\Work`\COSTCA`\CSV`\trackcal.csv'
+ CategoryInfo : ParserError: (:) [], ParseException
+ FullyQualifiedErrorId : FromKeywordNotAllowed**
Script:
#CALGARY
[io.file]::readalltext("`\`\DYNAMICS`\D`$`\Work`\COSTCA`\CSV`\trackcalgp.csv").replace("89400","0089400") | Out-File "`\`\DYNAMICS`\D`$`\Work`\COSTCA`\CSV`\trackcal1.csv" -Encoding ascii –Force
[io.file]::readalltext("`\`\DYNAMICS`\D`$`\Work`\COSTCA`\CSV`\trackcal1.csv").replace(".0","") | Out-File "`\`\DYNAMICS`\D`$`\Work`\COSTCA`\CSV`\trackcal2.csv" -Encoding ascii –Force
[io.file]::readalltext("`\`\DYNAMICS`\D`$`\Work`\COSTCA`\CSV`\trackcal2.csv").replace('"',"") | Out-File "`\`\DYNAMICS`\D`$`\Work`\COSTCA`\CSV`\trackcal.csv" -Encoding ascii –Force
$text = [IO.File]::ReadAllText("`\`\DYNAMICS`\D`$`\Work`\COSTCA`\CSV`\trackcal.csv")
[IO.File]::WriteAllText("`\`\DYNAMICS`\D`$`\Work`\COSTCA`\CSV`\trackcal.csv", $text.TrimEnd())
#MONTREAL
[io.file]::readalltext("`\`\DYNAMICS`\D`$`\Work`\COSTCA`\CSV`\trackmtlgp.csv").replace("89400","0089400") | Out-File "`\`\DYNAMICS`\D`$`\Work`\COSTCA`\CSV`\trackmtl1.csv" -Encoding ascii –Force
[io.file]::readalltext("`\`\DYNAMICS`\D`$`\Work`\COSTCA`\CSV`\trackmtl1.csv").replace(".0","") | Out-File "`\`\DYNAMICS`\D`$`\Work`\COSTCA`\CSV`\trackmtl2.csv" -Encoding ascii –Force
[io.file]::readalltext("`\`\DYNAMICS`\D`$`\Work`\COSTCA`\CSV`\trackmtl2.csv").replace('"',"") | Out-File "`\`\DYNAMICS`\D`$`\Work`\COSTCA`\CSV`\trackmtl.csv" -Encoding ascii –Force
$text = [IO.File]::ReadAllText("`\`\DYNAMICS`\D`$`\Work`\COSTCA`\CSV`\trackmtl.csv")
[IO.File]::WriteAllText("`\`\DYNAMICS`\D`$`\Work`\COSTCA`\CSV`\trackmtl.csv", $text.TrimEnd())
#TORONTO
[io.file]::readalltext("`\`\DYNAMICS`\D`$`\Work`\COSTCA`\CSV`\tracktorgp.csv").replace("89400","0089400") | Out-File "`\`\DYNAMICS`\D`$`\Work`\COSTCA`\CSV`\tracktor1.csv" -Encoding ascii –Force
[io.file]::readalltext("`\`\DYNAMICS`\D`$`\Work`\COSTCA`\CSV`\tracktor1.csv").replace(".0","") | Out-File "`\`\DYNAMICS`\D`$`\Work`\COSTCA`\CSV`\tracktor2.csv" -Encoding ascii –Force
[io.file]::readalltext("`\`\DYNAMICS`\D`$`\Work`\COSTCA`\CSV`\tracktor2.csv").replace('"',"") | Out-File "`\`\DYNAMICS`\D`$`\Work`\COSTCA`\CSV`\tracktor.csv" -Encoding ascii –Force
$text = [IO.File]::ReadAllText("`\`\DYNAMICS`\D`$`\Work`\COSTCA`\CSV`\tracktor.csv")
[IO.File]::WriteAllText("`\`\DYNAMICS`\D`$`\Work`\COSTCA`\CSV`\tracktor.csv", $text.TrimEnd())
#VANCOUVER
[io.file]::readalltext("`\`\DYNAMICS`\D`$`\Work`\COSTCA`\CSV`\trackvangp.csv").replace("89400","0089400") | Out-File "`\`\DYNAMICS`\D`$`\Work`\COSTCA`\CSV`\trackvan1.csv" -Encoding ascii –Force
[io.file]::readalltext("`\`\DYNAMICS`\D`$`\Work`\COSTCA`\CSV`\trackvan1.csv").replace(".0","") | Out-File "`\`\DYNAMICS`\D`$`\Work`\COSTCA`\CSV`\trackvan2.csv" -Encoding ascii –Force
[io.file]::readalltext("`\`\DYNAMICS`\D`$`\Work`\COSTCA`\CSV`\trackvan2.csv").replace('"',"") | Out-File "`\`\DYNAMICS`\D`$`\Work`\COSTCA`\CSV`\trackvan.csv" -Encoding ascii –Force
$text = [IO.File]::ReadAllText("`\`\DYNAMICS`\D`$`\Work`\COSTCA`\CSV`\trackvan.csv")
[IO.File]::WriteAllText("`\`\DYNAMICS`\D`$`\Work`\COSTCA`\CSV`\trackvan.csv", $text.TrimEnd())
#UPLOAD
$SQLServer = "DYNAMICS" #use Server`\Instance for named SQL instances!
$SQLDBName = "RDOT"
$SqlQuery1 = #"
CREATE TABLE #Tmp_TRACK
`(
`[CSTPONBR`] `[char`]`(21`) NOT NULL,
`[Tracking_Number`] `[char`]`(41`) NOT NULL
`)
CREATE TABLE #Tmp_TRACK1
`(
`[SOPNUMBE`] `[char`]`(21`) NOT NULL,
`[CSTPONBR`] `[char`](21) NOT NULL,
`[Tracking_Number`] `[char`]`(41`) NOT NULL
`)
BULK INSERT #Tmp_TRACK
FROM 'D:`\Work`\COSTCA`\CSV`\trackcal.csv'
WITH `(
FIRSTROW = 2,
DATAFILETYPE='char',
FIELDTERMINATOR=','
`);
INSERT INTO #Tmp_TRACK1
SELECT
SOP10100.SOPNUMBE,
#Tmp_TRACK.CSTPONBR,
#Tmp_TRACK.Tracking_Number
FROM
SOP10100 INNER JOIN
#Tmp_TRACK ON
SOP10100.CSTPONBR = #Tmp_TRACK.CSTPONBR AND
SOP10100.SOPTYPE = 3
INSERT INTO SOP10107 `(SOPNUMBE, SOPTYPE, Tracking_Number`)
SELECT SOPNUMBE, 3, TRACKING_NUMBER FROM #Tmp_TRACK1
select * from sop10107 where sopnumbe in `(SELECT SOPNUMBE from SOP10100 where SOPTYPE = 3 and CUSTNMBR = 'COSTCA' and DOCDATE = CONVERT`(Datetime, FLOOR(CONVERT`(float,GETDATE`(`)`)`)`)`)
drop table #TMP_TRACK
drop table #TMP_TRACK1
"#
$SqlQuery2 = "select * from IV00101 where ITEMNMBR = 'B16P'"
$SqlQuery3 = "select * from IV00101 where ITEMNMBR = 'B16P'"
$SqlQuery4 = "select * from IV00101 where ITEMNMBR = 'B16P'"
$SqlQuery5 = "select * from IV00101 where ITEMNMBR = 'B16P'"
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Server = $SQLServer; Database = $SQLDBName; Integrated Security = False; User ID = sa; Password = mypassword"
$SqlCmd1 = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd2 = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd3 = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd4 = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd5 = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd1.CommandText = $SqlQuery1
$SqlCmd2.CommandText = $SqlQuery2
$SqlCmd3.CommandText = $SqlQuery3
$SqlCmd4.CommandText = $SqlQuery4
$SqlCmd5.CommandText = $SqlQuery5
$SqlCmd1.Connection = $SqlConnection
$SqlCmd2.Connection = $SqlConnection
$SqlCmd3.Connection = $SqlConnection
$SqlCmd4.Connection = $SqlConnection
$SqlCmd5.Connection = $SqlConnection
$SqlAdapter1 = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter2 = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter3 = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter4 = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter5 = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter1.SelectCommand = $SqlCmd1
$SqlAdapter2.SelectCommand = $SqlCmd2
$SqlAdapter3.SelectCommand = $SqlCmd3
$SqlAdapter4.SelectCommand = $SqlCmd4
$SqlAdapter5.SelectCommand = $SqlCmd5
$DataSet1 = New-Object System.Data.DataSet
$DataSet2 = New-Object System.Data.DataSet
$DataSet3 = New-Object System.Data.DataSet
$DataSet4 = New-Object System.Data.DataSet
$DataSet5 = New-Object System.Data.DataSet
$SqlAdapter1.Fill($DataSet1)
$SqlAdapter2.Fill($DataSet2)
$SqlAdapter3.Fill($DataSet3)
$SqlAdapter4.Fill($DataSet4)
$SqlAdapter5.Fill($DataSet5)
$SqlConnection.Close()
#next line is a pause
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
clear
$DataSet1.Tables[0]
$DataSet2.Tables[0]
$DataSet3.Tables[0]
$DataSet4.Tables[0]
$DataSet5.Tables[0]
As you can see I escaped lots of characters that I thought powershell would freak out about. I would not be surprised if part of the problem is related to this.
Any help is greatly appreciated!

\ , (/), and [/] don't need to be escaped. Take out all of that as it's somewhat confusing and will probably be error prone.
But the error you're getting indicates that the from keyword is not supported (it looks like this is in reference to the BULK INSERT statement you're using. What version of SQL server is this?

Related

Convert date format to CSV export

I'm new to Poweshell, and I made a script that the result of an SQL Select is exported to csv. However I have two columns that are in the date format mm-dd-yyyy and I would like it to be in the format yyyy-MM-dd HH: mm: ss.fff. I was able to transform just one column, in the other I couldn't find a way to convert.
Could someone help me to convert the two columns?
#Connect to SQL and run QUERY
$SQLServer = "xxxx"
$SQLDBName = "xxxx"
$SQLUsername = "xxxx"
$SQLPassword = "nxxx"
$OuputFile = "c:\SQL_Export.csv"
$SqlQuery = "SELECT
rtrim(HANDLE) as Handle,
rtrim(EMPRESA) as Empresa,
rtrim(FILIAL) as Filial,
rtrim(OPERACAO) as Operacao,
rtrim(PESSOA) as Pessoa,
rtrim(dataemissao) as Dataemissao,
rtrim(documentodigitado) as Documentodigitado,
rtrim(dataultimaliq) as Dataultimaliq,
rtrim(ehprevisao) as Ehprevisao,
rtrim(status) as Status,
rtrim(entradasaida) as Entradasaida
FROM [$SQLDBName].[dbo].[FN_DOCUMENTOS]
where DATAULTIMALIQ >= '20200101'
ORDER BY handle ASC"
##Delete the output file if it already exists
If (Test-Path $OuputFile ){
Remove-Item $OuputFile
}
Write-Host "INFO: Exporting data from $SQLDBName to $OuputFile" -foregroundcolor white -backgroundcolor blue
## - Connect to SQL Server using non-SMO class 'System.Data':
$SqlConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Server = $SQLServer; Database = $SQLDBName; User ID = $SQLUsername; Password = $SQLPassword"
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd.CommandText = $SqlQuery
$SqlCmd.Connection = $SqlConnection
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter.SelectCommand = $SqlCmd
$DataSet = New-Object System.Data.DataSet
$SqlAdapter.Fill($DataSet)
$SqlConnection.Close()
#Output RESULTS to CSV
$DataSet.Tables[0] | select-Object -ExcludeProperty Dataemissao #{Name="Dataemissao";Expression={([datetime]$_.Dataemissao).ToString("yyyy-MM-dd HH:mm:ss.fff")}}, * | Export-Csv $OuputFile
(Get-Content $OuputFile) | Foreach-Object {$_ -replace '"', ""} | Set-Content $OuputFile -Encoding `UTF8`
the columns I need to convert are, "Dataemissao" and "Dataultimaliq"
In this case, you would need a very long line in the Select-Object:
$DataSet.Tables[0] |
Select-Object -ExcludeProperty Dataemissao, Dataultimaliq #{Name = "Dataemissao"; Expression= { '{0:yyyy-MM-dd HH:mm:ss.fff}'-f [datetime]$_.Dataemissao }},
#{Name = "Dataultimaliq"; Expression= { '{0:yyyy-MM-dd HH:mm:ss.fff}'-f [datetime]::ParseExact($_.Dataultimaliq, 'MMM dd yyyy hh:mm tt', [cultureinfo]"en-US") }},
* | Export-Csv -Path $OuputFile -Encoding UTF8 -NoTypeInformation
OR, you could add a small helper function above the code like
function Format-Date () {
param (
[string]$dateString,
[string]$format = 'MMM dd yyyy hh:mm tt'
)
$date = Get-Date
if ([datetime]::TryParseExact($dateString, $format, [cultureinfo]"en-US", 0, [ref]$date)) {
return '{0:yyyy-MM-dd HH:mm:ss.fff}'-f $date
}
}
and use that for the Dataultimaliq:
#{Name = "Dataultimaliq"; Expression= { Format-Date $_.Dataultimaliq }},
As you can see, I've put a second parameter $format in that defaults to ''MMM dd yyyy hh:mm tt', because that is the format the returned Dataultimaliq field is in.
You can also use that on the Dataemissao field, but I don't know what format that is in.. (apparently, your system can cast it to a DateTime object without any problems)
I see you read the csv file in later and remove the quotes from it. This can lead to various problems, because sometimes quotes are needed in a CSV file and you should not simply remove all of them. Have a look at this answer for code how you can do that safely
P.S. '{0:yyyy-MM-dd HH:mm:ss.fff}'-f [datetime]$_.Dataemissao is a more 'PowerShelly' way of getting a date in a specific format. It returns the same as ([datetime]$_.Dataemissao).ToString("yyyy-MM-dd HH:mm:ss.fff"), but is more concise.

PowerShell Script that Queries SQL Table to CSV File using Loop

I have a basic SQL table of Employees. Using a powershell script I want to export all the employees who have made over 1000 sales to a .csv file and the rest into a different .csv file. I want to accomplish this task by using a loop. I am new to powershell and want to learn the foundations. Can anyone help?
SQL Table (not real employees)
This is what I have so far:
$connection.Open()
[System.Data.SqlClient.SqlDataReader]$result = $cmd.ExecuteReader()
$highDestFile = "C:\high-sales.csv"
$lowDestFile = "C:\low-sales.csv"
while($result.Read()) {
$ename = $result.GetValue(3);
$job = $result.GetValue(4);
$sales = $result.GetValue(7);
$tableArray = New-Object System.Collections.ArrayList
$tableArray.Add($ename)
$tableArray.Add($job)
$tableArray.Add($sales)
if($sales -ge 1000) {
Out-File -FilePath $highDestFile -InputObject $tableArray -Encoding ASCII -Append
} else {
Out-File -FilePath $lowDestFile -InputObject $tableArray -Encoding ASCII -Append
}
}
$connection.Close()
I'm not real familiar with the method you're using to get your results, but I think I have something similar that might be easier to work with for you. It will get all results into PS, and you can filter things from there, rather than getting one result at a time. You obviously know how to make your own SqlConnection and SqlCommand, I'm just including them for future readers to reference.
# Define SQL query
$sqlQuery = #"
SELECT *
FROM MyTable
"#
# Create a SqlConnection to connect to the SQL DB
$sqlConnection = New-Object System.Data.SqlClient.SqlConnection
$sqlConnection.ConnectionString = "Server = $SqlServer; Database =$SqlCatalog; User Id = $User; Password = $Password"
# Create a SqlCommand object to define the query
$sqlCmd = New-Object System.Data.SqlClient.SqlCommand
$sqlCmd.CommandText = $sqlQuery
$sqlCmd.Connection = $sqlConnection
# Create a SqlAdapter that actually does the work and manages everything
$sqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$sqlAdapter.SelectCommand = $sqlCmd
# Create an empty DataSet for the query to fill with its results
$dataSet = New-Object System.Data.DataSet
# Execute the query and fill the DataSet (then disconnect)
$sqlAdapter.Fill($dataSet)
$sqlConnection.Close()
# Convert DataSet table to array for ease of use
[Array]$Results = $dataSet.Tables[0]
Beyond that you could just use a pair of Where statements to filter your results, and output to files.
$Results | ?{[int]$_.Sales -ge 1000} | Set-Content $highDestFile
$Results | ?{[int]$_.Sales -lt 1000} | Set-Content $lowDestFile

Powershell import csv to SQL queries, export multiple csvs

I'm struggling to get my head around this one, I've only just begun looking at scripting in SQL, and my powershell is very limited. The requirments are basically this:
Utilisng Powershell, import a csv file which contains one column that needs to feed into multiple SQL queries via a loop, exporting a seperate csv file for each different query.
example import of csv:
Project (heading)
1000
1001
1002
Powershell:
$importProjectsCSV = e:\Projects.csv
$server = servername
$database = database
import-csv $importProjectsCSV | ForEach-Object {
$query = "
Select ProjectLeader, ProjectTitle
FROM dbo.PROJECTS
Where Project = $_.Project;
Select ProjectClient, Name
FROM dbo.CLIENTS
Where Project = $_.Project;
$connectionTemplate = "Data Source={0};Integrated Security=SSPI;Initial Catalog={1};"
$connectionString = [string]::Format($connectionTemplate, $server, $database)
$connection = New-Object System.Data.SqlClient.SqlConnection
$connection.ConnectionString = $connectionString
$command = New-Object System.Data.SqlClient.SqlCommand
$command.CommandText = $query
$command.Connection = $connection
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter.SelectCommand = $command
$DataSet = New-Object System.Data.DataSet
$SqlAdapter.Fill($DataSet)
$connection.Close()
$dataset.Table[0] | Export-csv "E:\" + $_.ProjectName + ".csv"
$dataset.Table[1] | Export-csv "E:\" + $_.ProjectName + ".csv"
The problem is that the variable isn't coming into the SQL query.
Is there a better way to handle this type of example?
Appreciate any pointers
Paul.
I would do something like this:
I must admit i havent been able to test it, and personally i usually use c# to query sql servers. So i might have gone a bit wrong somewhere.
$importProjectsCSV = e:\Projects.csv
$server = servername
$database = database
$Projects = Import-Csv -Path $importProjectsCSV | % {$_.Project}
$DS_Projects = New-Object System.Data.DataSet
$DS_Clients = New-Object System.Data.DataSet
$query_pro = "Select ProjectLeader, ProjectTitle, Project FROM dbo.PROJECTS";
$query_Clients = "Select ProjectClient, Name, Project FROM dbo.CLIENTS";
$connectionTemplate = "Data Source={0};Integrated Security=SSPI;Initial Catalog={1};"
$connectionString = [string]::Format($connectionTemplate, $server, $database)
$connection = New-Object System.Data.SqlClient.SqlConnection
$connection.ConnectionString = $connectionString
$connection.Open()
$command = $connection.CreateCommand();
$command.CommandText = $query_pro;
$sqlAdap = New-Object System.Data.SqlClient.SqlDataAdapter($command)
$sqlAdap.Fill($DS_Projects)
$command2 = $connection.CreateCommand();
$command2.CommandText = $query_Clients;
$sqlAdap2 = New-Object System.Data.SqlClient.SqlDataAdapter($command2)
$sqlAdap2.Fill($DS_Clients)
$connection.Close();
foreach($project in $Projects)
{
$DS_Projects.Tables[0].Select("Project=$project") | Export-Csv "E:\$project.csv"
$DS_Clients.Tables[0].Select("Project=$project") | Export-Csv "E:\$project.csv"
}
If I get every right you could do this with something like this:
$Projects = Import-Csv -Path 'C:\Temp\Projects.csv'
ForEach ($Project in $Projects.Projects) {
$Query= #"
Select ProjectLeader, ProjectTitle
FROM dbo.PROJECTS
Where Project = '%{0}';
"# -f $Project
# just dummy action
$results = Invoke-Sqlcmd -ServerInstance "foo" -Database "bar" -Query $Query
# In Case results is a dataset do something like
$results | Export-Csv -Path ("E:\{0}.csv" -f $Project )
}

Insert Microsoft Updates into Database

I'm trying to modify this script so that it inserts the installed updates into an SQL Server database table.
$conn = New-Object System.Data.SqlClient.SqlConnection
$conn.ConnectionString = "Data Source=sqlserver; Initial Catalog=updates; Integrated Security=SSPI;"
$conn.Open()
$cmd = New-Object System.Data.SqlClient.SqlCommand
$cmd.Connection = $conn
$cmd = $conn.CreateCommand()
$wu = new-object -com “Microsoft.Update.Searcher”
$totalupdates = $wu.GetTotalHistoryCount()
$all = $wu.QueryHistory(0,$totalupdates)
$OutputCollection= #()
Foreach ($update in $all){
$Regex = “KB\d*”
$KB = $string | Select-String -Pattern $regex | Select-Object { $_.Matches }
$output = New-Object -TypeName PSobject
$output | add-member NoteProperty “HotFix ID” -value $KB.‘ $_.Matches ‘.Value
$output | add-member NoteProperty “Title” -value $string
$OutputCollection += $output
$cmd.CommandText += "INSERT INTO dbo.updates (hotfixid, hotfixdescription) VALUES ('$($kb.'$_.Matches'.Value)', ('$($string)'))"
}
$cmd.ExecuteNonQuery()
$conn.close()
At the moment, I'm getting correct number of rows for updates in sql server but it isn't showing hotfixid and in hotfix descriptien columns there is a only one update in all rows.
Thanks!
Do the INSERTs inside the loop. I would, however, recommend that you use prepared statements instead of building the SQL statements via string concatenation. Also, there's no need to build $OutputCollection objects when you're not using it anywhere.
Something like this should work:
...
$wu.QueryHistory(0, $totalupdates) | % {
$KB = $_.Title | ? { $_ -match '(KB\d+)' } | % { $matches[1] }
$cmd = $conn.CreateCommand()
$cmd.CommandText = "INSERT INTO dbo.updates (hotfixid, hotfixdescription) " +
"VALUES (#id, #descr)"
$cmd.Parameters.AddWithValue("#id", $KB)
$cmd.Parameters.AddWithValue("#descr", $_.Title)
$cmd.Prepare()
$cmd.ExecuteNonQuery()
}
...
Untested, though, since I don't have an SQL Server at hand. I also suspect that there's a more efficient way to handle the prepared statements, but I'm not that familiar with SQL Server.

Powershell array correlation to SQL table dataset from powershell

First off, I'm new to stack. I have referenced stack many times in the past, but recently I have been stuck on this issue for quite sometime. So here goes.
My goal:
I am attempting to correlate an array output from VMware that matches a custom value on each VM machine. ( an asset ID ) to a value ( ID Key ) on a microsoft SQL 2000 server.
As such, since this server is pre 2005 I am unable to use the invoke-sqlcmd powershell command. I have to utilize the full SQL connection string and command structure to return a value out of this database. This sql statement and script works fine on its own. Meaning that the sql portion of this script, functioning on its own will pull results out of the database with a manual tag number put in place of my variable "$etag". I'm fairly new to powershell, and sql use from powershell.
So here is my script with names of the protected taken out.
#========================================================================
# Created on: 12/4/2013 2:01 PM
# Created by: Shaun Belcher
# Filename:
#========================================================================
function get-inventory
{
Add-PSSnapin VMware.VimAutomation.Core
$date=get-date
$vcenterserver = #("srv-1","srv-2","srv-3")
Connect-VIServer -server $vcenterserver
$toAddr="user#domain.com"
$fromAddr="user#domain.com"
$smtpsrv="mail.domain.com"
#Variables
$mdesks=#()
$sqlServer = "serverdb"
$sqlDBNAME = "instance"
$sqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$sqlConnection = New-Object System.Data.SqlClient.SqlConnection
$DataSet = New-Object System.Data.DataSet
$sqlCmd = New-Object System.Data.SqlClient.SqlCommand
$SqlCmd.connection = $sqlConnection
$sqlAdapter.SelectCommand = $sqlCmd
#db Connection
$sqlConnection.ConnectionString = "Server = $sqlServer; Database = $sqlDBname; Integrated Security=True;"
$SqlCmd.connection = $SqlConnection
$SqlCmd.commandtext = $sqlQuery
$sqlAdapter.SelectCommand = $sqlCmd
$sqlQuery += "SELECT INVHARDW_PropTag as proptag, invhardw_clientID as ClientID, invhardw_notes as Notes FROM INV_Hardware where invhardw_proptag = '$etag';"
$SqlCmd.commandtext = $sqlQuery
$sqlAdapter.SelectCommand = $sqlCmd
$sqlAdapter.Fill($DataSet)
$DataSet.Tables[0]
$sqlConnection.Close()
$mdesks = #($DataSet.Tables[0] | select propTag, ClientID, Notes)
$virtuals= #(Get-VM | select Name,vmhost,memoryMB,#{N="Datastore";E={[string]::Join(',',(Get-Datastore -Id $_.DatastoreIdList | Select -ExpandProperty Name))}})
$etags = #(Get-vm | Get-Annotation |select value,#{N="mDeskNote";E={[string]::Join(',',($mdesk | Where-Object {$mdesks.propTag = $_;}))}},#{N="mDeskClientID";E={[string]::Join(',',($mdesk | Where-Object {$mdesks.propTag = $_;}))}})
if($virtuals -ne $null){
$body = #("
<center><table border=1 width=50 % cellspacing=0 cellpadding=8 bgcolor=Black cols=3>
<tr bgcolor=White><td>Virtual Machine</td><td>Host Machine</td><td>Memory Allocated</td><td>DatastoreList</td><td>Asset Tag</td><td>App Note</td><td>App Client ID</td></tr>")
$i = 0
do {
#if($i % 2){$body += "<tr bgcolor=#D2CFCF><td>$($virtuals[$i].Name)</td></tr>";$i++}
#else {$body += "<tr bgcolor=#EFEFEF><td>$($virtuals[$i].Name)</td></tr>";$i++}
if($i % 2){$body += "<tr bgcolor=#D2CFCF><td>$($virtuals[$i].Name)</td><td>$($virtuals[$i].VMHost)</td><td>$($virtuals[$i].MemorymB)</td><td>$($virtuals[$i].datastore)</td><td>$($etags[$i].value)</td><td>$mdesks[$i].notes</td><td>$mdesks[$i].ClientID</td></tr>";$i++}
else {$body += "<tr bgcolor=#EFEFEF><td>$($virtuals[$i].Name)</td><td>$($virtuals[$i].VMHost)</td><td>$($virtuals[$i].memorymb)</td><td>$($virtuals[$i].datastore)</td><td>$($etags[$i].value)</td><td>$mdesks[$i].notes</td><td>$mdesks[$i].ClientID</td></tr>";$i++}
}
while ($virtuals[$i] -ne $null)
$body += "</table></center>"
# Send email.
if($attachmentPref){
$virtuals | Export-CSV "Inventory $($date.month)-$($date.day)-$($date.year).csv"
Send-MailMessage -To "$toAddr" -From "$fromAddr" -Subject "$vcenterserver Inventory = $countvms" -Body "$body" -Attachments "Inventory $($date.month)-$($date.day)-$($date.year).csv" -SmtpServer "$smtpsrv" -BodyAsHtml
Remove-Item "Inventory $($date.month)-$($date.day)-$($date.year).csv"
}
Else{
Send-MailMessage -To "$toAddr" -From "$fromAddr" -Subject "Inventory $vcenterserver = $countvms" -Body "$body" -SmtpServer "$smtpsrv" -BodyAsHtml
}
}
Disconnect-VIServer -Server $vcenterserver -Confirm:$false exit
get-inventory
This returns the information and sends it in an email with columns and rows of the information. Again, these are two working scripts that just do not return the result that is sought after.