Powershell SQL query results convertto-XML - sql

I have been having quite the time trying to figure this out. Let me try to explain what I am trying to accomplish, I hope i can be clear enough.
I am sending two queries to an MSSQL database and receiving them back. The below code works perfect, however I would like to manipulate the format of the XML a bit before it writes to the XML file. I currently get 3 columns (serviceGroupName, numAccounts, numDevices) I would like to accomplish 1 of 2 things:
1) Add a new column named "ReportType" and have it fill in "Monthly" Or "Total" depending on if it is pass 1 or 2 of the foreach loop (SQLQuery1 is Monthly report, and SQLQuery2 is Total number since inception)
2) Create a new PSObject and have it fill in the appropriate information such as the data it receives back (serviceGroupName, numAccounts, numDevices)
Below is my current code. As i mentioned it does work and it generated an XML but i would like to add some more information before the pipe to ConvertTo-XML if possible.
### Dates to use
$Date = (Get-Date -f MM-dd-yyyy)
$FDoTM = ((Get-Date -Day 01).AddMonths(0)).AddDays(0)
$LDo2PM = ((Get-Date -Day 01).AddMonths(-1)).AddDays(-1)
$TempDir = "C:\Temp"
$WebDir = #("\\x.x.x.x\c$\inetpub\wwwroot\Reports\Accounts","\\x.x.x.x\c$\inetpub\wwwroot\Reports\Accounts")
### Something
$OutputXML = "$Date-Monthly-AccountReport.xml"
### Connection settings, uses windows authentication
$DBServer = "OMMITED"
$databasename = "OMMITED"
$Connection = new-object system.data.sqlclient.sqlconnection #Set new object to connect to sql database
$Connection.ConnectionString ="server=$DBServer;database=$databasename;trusted_connection=True" # Connectiongstring setting for local machine database with window authentication
Write-host "Connection Information:" -foregroundcolor yellow -backgroundcolor black
$Connection #List connection information
### Connect to Database and Run Query
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand #setting object to use sql commands
$OutputHeader1 = "This Month's counts"
$SqlQuery1 = #"
SET NOCOUNT ON;
WITH AccountDeviceStats(serviceGroupName,numAccounts,numDevices)
AS
(
SELECT svg.name,COUNT(acct.serviceGroupId) as Accounts, NULL FROM bm_account acct WITH (NOLOCK)
INNER JOIN bm_servicegroup svg WITH (NOLOCK) ON svg.servicegroupId = acct.serviceGroupId
where acct.CreateStamp between '$($LDo2PM)' and '$($FDoTM)'
GROUP BY acct.serviceGroupId,svg.name
UNION ALL
SELECT svg.name, NULL, COUNT(device.serviceGroupId) as Devices FROM bm_device device WITH (NOLOCK)
INNER JOIN bm_servicegroup svg WITH (NOLOCK) ON svg.servicegroupId = device.serviceGroupId, bm_account acct
where device.accountID=acct.accountId and acct.CreateStamp between '$($LDo2PM)' and '$($FDoTM)'
GROUP BY device.serviceGroupId,svg.name
)
SELECT ad1.serviceGroupName,ad1.numAccounts,ad2.numDevices FROM AccountDeviceStats ad1
INNER JOIN AccountDeviceStats ad2 ON ad1.serviceGroupName = ad2.serviceGroupName
WHERE ad1.numAccounts IS NOT NULL AND ad2.numDevices IS NOT NULL
ORDER BY numAccounts DESC,numDevices DESC
"#
$OutputHeader2 = "Total Counts"
$SqlQuery2 = #"
SET NOCOUNT ON;
WITH AccountDeviceStats(serviceGroupName,numAccounts,numDevices)
AS
(
SELECT svg.name,COUNT(acct.serviceGroupId) as Accounts, NULL FROM bm_account acct WITH (NOLOCK)
INNER JOIN bm_servicegroup svg WITH (NOLOCK) ON svg.servicegroupId = acct.serviceGroupId
where acct.CreateStamp < '12-31-2099'
GROUP BY acct.serviceGroupId,svg.name
UNION ALL
SELECT svg.name, NULL, COUNT(device.serviceGroupId) as Devices FROM bm_device device WITH (NOLOCK)
INNER JOIN bm_servicegroup svg WITH (NOLOCK) ON svg.servicegroupId = device.serviceGroupId, bm_account acct
where device.accountID=acct.accountId and acct.CreateStamp < '12-31-2099'
GROUP BY device.serviceGroupId,svg.name
)
SELECT ad1.serviceGroupName,ad1.numAccounts,ad2.numDevices FROM AccountDeviceStats ad1
INNER JOIN AccountDeviceStats ad2 ON ad1.serviceGroupName = ad2.serviceGroupName
WHERE ad1.numAccounts IS NOT NULL AND ad2.numDevices IS NOT NULL
ORDER BY numAccounts DESC,numDevices DESC
"#
$sqlQueries = #($SqlQuery1, $SqlQuery2)
$Results = #()
Foreach ($Query in $sqlQueries){
$Connection.open()
Write-host "Connection to database successful." -foregroundcolor green -backgroundcolor black
$SqlCmd.CommandText = $Query
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter.SelectCommand = $SqlCmd
$SqlCmd.Connection = $Connection
$DataSet = New-Object System.Data.DataSet
$SqlAdapter.Fill($DataSet)
$Connection.Close()
$Results += $DataSet.Tables[0]
($Results | ConvertTo-XML -NoTypeInformation).Save("$TempDir\$OutputXML")
}
if ((Get-ChildItem $TempDir -filter "$Date-*.xml").count -gt 0){
Foreach ($file in (Get-ChildItem $TempDir -filter "$Date-*.xml" -recurse)){
Foreach ($webserver in $WebDir){
Copy-Item $file.fullname "$webserver\$file" -force
}
Remove-Item $file.fullname -force
}
}
Here is the output formatting of the XML
<?xml version="1.0"?>
<Objects>
<Object>
<Property Name="serviceGroupName">ServiceGroup1</Property>
<Property Name="numAccounts">15</Property>
<Property Name="numDevices">28</Property>
<Property Name="RowError" />
<Property Name="RowState">Unchanged</Property>
<Property Name="Table">
<Property>System.Data.DataRow</Property>
</Property>
<Property Name="ItemArray">
<Property>ServiceGroup1</Property>
<Property>15</Property>
<Property>28</Property>
</Property>
<Property Name="HasErrors">False</Property>
</Object>
<Object>
<Property Name="serviceGroupName">ServiceGroup1</Property>
<Property Name="numAccounts">45</Property>
<Property Name="numDevices">69</Property>
<Property Name="RowError" />
<Property Name="RowState">Unchanged</Property>
<Property Name="Table">
<Property>System.Data.DataRow</Property>
</Property>
<Property Name="ItemArray">
<Property>ServiceGroup1</Property>
<Property>45</Property>
<Property>69</Property>
</Property>
<Property Name="HasErrors">False</Property>
And one last thing. If it's possible to remove the excess bloat from the XML, as you can see it doubles the data output because it creates a node named ItemArray with all of the same information.
I hope this is easy enough to understand. If you need any more information, please let me know. And thank you in advance for any and all help.

I think all you need to do is to update your two T-sql queries within the powershell script. First one, add code like following:
...., "Monthly" as ReportType FROM AccountDeviceStats ad1...
Second one, add code like following:
...., "Total" as ReportType FROM AccountDeviceStats ad1...
### Dates to use
$Date = (Get-Date -f MM-dd-yyyy)
$FDoTM = ((Get-Date -Day 01).AddMonths(0)).AddDays(0)
$LDo2PM = ((Get-Date -Day 01).AddMonths(-1)).AddDays(-1)
$TempDir = "C:\Temp"
$WebDir = #("\\x.x.x.x\c$\inetpub\wwwroot\Reports\Accounts","\\x.x.x.x\c$\inetpub\wwwroot\Reports\Accounts")
### Something
$OutputXML = "$Date-Monthly-AccountReport.xml"
### Connection settings, uses windows authentication
$DBServer = "OMMITED"
$databasename = "OMMITED"
$Connection = new-object system.data.sqlclient.sqlconnection #Set new object to connect to sql database
$Connection.ConnectionString ="server=$DBServer;database=$databasename;trusted_connection=True" # Connectiongstring setting for local machine database with window authentication
Write-host "Connection Information:" -foregroundcolor yellow -backgroundcolor black
$Connection #List connection information
### Connect to Database and Run Query
$SqlCmd = New-Object System.Data.SqlClient.SqlCommand #setting object to use sql commands
$OutputHeader1 = "This Month's counts"
$SqlQuery1 = #"
SET NOCOUNT ON;
WITH AccountDeviceStats(serviceGroupName,numAccounts,numDevices)
AS
(
SELECT svg.name,COUNT(acct.serviceGroupId) as Accounts, NULL FROM bm_account acct WITH (NOLOCK)
INNER JOIN bm_servicegroup svg WITH (NOLOCK) ON svg.servicegroupId = acct.serviceGroupId
where acct.CreateStamp between '$($LDo2PM)' and '$($FDoTM)'
GROUP BY acct.serviceGroupId,svg.name
UNION ALL
SELECT svg.name, NULL, COUNT(device.serviceGroupId) as Devices FROM bm_device device WITH (NOLOCK)
INNER JOIN bm_servicegroup svg WITH (NOLOCK) ON svg.servicegroupId = device.serviceGroupId, bm_account acct
where device.accountID=acct.accountId and acct.CreateStamp between '$($LDo2PM)' and '$($FDoTM)'
GROUP BY device.serviceGroupId,svg.name
)
SELECT ad1.serviceGroupName,ad1.numAccounts,ad2.numDevices, ""Monthly"" as ReportType FROM AccountDeviceStats ad1
INNER JOIN AccountDeviceStats ad2 ON ad1.serviceGroupName = ad2.serviceGroupName
WHERE ad1.numAccounts IS NOT NULL AND ad2.numDevices IS NOT NULL
ORDER BY numAccounts DESC,numDevices DESC
"#
$OutputHeader2 = "Total Counts"
$SqlQuery2 = #"
SET NOCOUNT ON;
WITH AccountDeviceStats(serviceGroupName,numAccounts,numDevices)
AS
(
SELECT svg.name,COUNT(acct.serviceGroupId) as Accounts, NULL FROM bm_account acct WITH (NOLOCK)
INNER JOIN bm_servicegroup svg WITH (NOLOCK) ON svg.servicegroupId = acct.serviceGroupId
where acct.CreateStamp < '12-31-2099'
GROUP BY acct.serviceGroupId,svg.name
UNION ALL
SELECT svg.name, NULL, COUNT(device.serviceGroupId) as Devices FROM bm_device device WITH (NOLOCK)
INNER JOIN bm_servicegroup svg WITH (NOLOCK) ON svg.servicegroupId = device.serviceGroupId, bm_account acct
where device.accountID=acct.accountId and acct.CreateStamp < '12-31-2099'
GROUP BY device.serviceGroupId,svg.name
)
SELECT ad1.serviceGroupName,ad1.numAccounts,ad2.numDevices, ""Total"" as ReportType FROM AccountDeviceStats ad1
INNER JOIN AccountDeviceStats ad2 ON ad1.serviceGroupName = ad2.serviceGroupName
WHERE ad1.numAccounts IS NOT NULL AND ad2.numDevices IS NOT NULL
ORDER BY numAccounts DESC,numDevices DESC
"#
$sqlQueries = #($SqlQuery1, $SqlQuery2)
$Results = #()
Foreach ($Query in $sqlQueries){
$Connection.open()
Write-host "Connection to database successful." -foregroundcolor green -backgroundcolor black
$SqlCmd.CommandText = $Query
$SqlAdapter = New-Object System.Data.SqlClient.SqlDataAdapter
$SqlAdapter.SelectCommand = $SqlCmd
$SqlCmd.Connection = $Connection
$DataSet = New-Object System.Data.DataSet
$SqlAdapter.Fill($DataSet)
$Connection.Close()
$Results += $DataSet.Tables[0]
($Results | ConvertTo-XML -NoTypeInformation).Save("$TempDir\$OutputXML")
}
if ((Get-ChildItem $TempDir -filter "$Date-*.xml").count -gt 0){
Foreach ($file in (Get-ChildItem $TempDir -filter "$Date-*.xml" -recurse)){
Foreach ($webserver in $WebDir){
Copy-Item $file.fullname "$webserver\$file" -force
}
Remove-Item $file.fullname -force
}
}

The original question asked how to remove the bloat from the XML as well. I was looking for a solution where the XML that I was generating from the SQL results had to be in an absolute specific format with the correct tags and everything in place. What I discovered was that once you have your dataset object ($DataSet) then if you look to see what methods and properties are available to it, ($DataSet | gm) then one of them is GetXML().
This automatically formats your SQL output such that each returned column (or column alias) is returned as a separate tag (although note, it does not generate an empty tag for a null value) so in this instance if you use $DataSet.GetXML() I would have expected to see output something along the lines of
<NewDataSet>
<Table>
<serviceGroupName>ServiceGroup1</serviceGroupName>
<numAccounts>15</numAccounts>
<numDevices>28</numDevices>
</Table>
</NewDataSet>
so no bloat!
As this is just a series of strings, you can then do things like ($Dataset.GetXML()).Replace('NewDataSet','OuterTag').Replace('Table','InnerTag') to give better labels to the XML. Once you are happy with this you can output
SET-CONTENT -PATH $xmlfilename -VALUE '<?xml version="1.0" ?>'
or some such to a file and then append the output from your GetXML() method so you have a much neater formatted piece of XML!
($DataSet.GetXML()).Replace('NewDataSet','OuterTagName').Replace('Table','InnerTagName') | ADD-CONTENT -PATH $xmlfilename

Related

Powershell outputs mixed between loops - SQL datasets [duplicate]

This question already has an answer here:
PowerShell output is crossing between functions
(1 answer)
Closed 2 years ago.
I have a PowerShell script that loops through list of 3 servers. A SQL script is run with Invoke-Sqlcmd and the result set is stored to variable $DS. At the end of the loop I return the records with with $DS.Tables.Rows.
But the results sets are getting mixed together. I tried using a Write-Host message to breakup the results. But they are still getting mixed together.
Why are the result getting mixed together in the output?
How can I separate the outputs between each loop?
Thanks
Object type
$DS | gm ............... TypeName: System.Data.DataSet
$DS.Tables | gm ........ TypeName: System.Data.DataTable
$DS.Tables.Rows | gm ... TypeName: System.Data.DataRow
Script
#########################>
# SQL servers
$PCList= #("GCOD139","GCOD039","GCOP039")
Write-Host ($PCList -join ", ")
# Query multiple servers
foreach ($PC in $PCList) {
Write-Host ($PC + "...") -ForegroundColor Yellow
# SQL parameters
$Params = #{
'ServerInstance' = $PC;
'Database' = 'master';
# 'Username' = 'svcBIPOC';
# 'Password' = 'bipoc2020*';
# 'InputFile' = "C:\ScriptFolder\TestSqlCmd.sql"
'Query' = '
SELECT
[Server]= ##SERVERNAME
--MB to GB
, REPLACE(name, ''MB'', ''GB'')
,[value]= CAST(value as int)/1000
, [value_in_use]= CAST(value_in_use as int)/1000
--, value, value_in_use, [description]
FROM sys.configurations
WHERE name like ''%server memory%''
ORDER BY name desc
OPTION (RECOMPILE);
'
}
# Capture SQL Dataset
# (Get-Date).ToSTring('s') + " SQL query start..."
$DS = Invoke-Sqlcmd #Params -As DataSet
#(Get-Date).ToSTring('s') + " SQL query end..."
Write-host "-----"
Write-host "SQL"
sleep -Seconds 5
$DS.Tables.Rows
sleep -Seconds 5
}
#########################
Stop using Write-Host to convey progress information - use Write-Progress for that instead!
$PCList= #("GCOD139","GCOD039","GCOP039")
Write-Progress -Activity "Query servers" -Status "About to query: $($PCList -join ", ")"
# Query multiple servers
foreach ($PC in $PCList) {
Write-Progress -Activity "Query servers" -Status "Querying: $PC"
# SQL parameters
$Params = #{
'ServerInstance' = $PC;
'Database' = 'master';
# 'Username' = 'svcBIPOC';
# 'Password' = 'bipoc2020*';
# 'InputFile' = "C:\ScriptFolder\TestSqlCmd.sql"
'Query' = '
SELECT
[Server]= ##SERVERNAME
--MB to GB
, REPLACE(name, ''MB'', ''GB'')
,[value]= CAST(value as int)/1000
, [value_in_use]= CAST(value_in_use as int)/1000
--, value, value_in_use, [description]
FROM sys.configurations
WHERE name like ''%server memory%''
ORDER BY name desc
OPTION (RECOMPILE);
'
}
# Capture SQL Dataset
$DS = Invoke-Sqlcmd #Params -As DataSet
$DS.Tables.Rows
}
Write-Progress -Activity "Query servers" -Completed
Now the progress messages won't interfere with the actual output from the function

Powershell script to get output through Sql query in table format attached in email?

The below script is resulting in the error below when attempt to send mail is made.
New-Object : A positional parameter cannot be found that accepts argument '='.
At line:22 char:18
+ ... onnection = New-Object System.Data.SqlClient.SqlConnection $SqlCon ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [New-Object], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.NewObjectCommand
Exception calling "Fill" with "1" argument(s): "Login failed for user ''."
At line:29 char:1
+ $SqlAdapter.Fill($DataSet)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : SqlException
Send-MailMessage : Cannot convert 'System.Object[]' to the type 'System.String' required by parameter 'Body'. Specified method is not supported.
At line:44 char:17
+ -BodyAsHtml $html_table `
+ ~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Send-MailMessage], ParameterBindingException
+ FullyQualifiedErrorId : CannotConvertArgument,Microsoft.PowerShell.Commands.SendMailMessage
$Servers = (Import-Csv -Path "D:\Scripts\input.csv").ComputerName
$SQLDBName = "ReportServer"
$SQLQuery = #"
SELECT Distinct
RL.RoleName,
USR.UserName
FROM
Catalog C
INNER JOIN Policies PL
ON C.PolicyID = PL.PolicyID
INNER JOIN PolicyUserRole PUR
ON PUR.PolicyID = PL.PolicyID
INNER JOIN Users USR
ON PUR.UserID = USR.UserID
INNER JOIN dbo.Roles RL
ON RL.RoleID = PUR.RoleID
WHERE RoleName = 'Content Manager'
ORDER BY USR.UserName
"#
# This code connects to the SQL server and retrieves the data
$SQLConnection = New-Object System.Data.SqlClient.SqlConnection $SqlConnection.ConnectionString = "Server = $Servers; Database = $SQLDBName;"
$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()
# This code outputs the retrieved data
$html = $DataSet.Tables[0] | ConvertTo-Html -fragment
$results = $DataSet.Tables | format-table -autosize | out-string
$mail_body = $results
# Send the email
$html_table = $dt | sort-object "Status" | ConvertTo-Html -Fragment
Send-MailMessage `
-From "Reporting.Services#accenture.com" `
-To 'aditi.m.singh#accenture.com' `
-Subject 'Sending the Attachment' `
-BodyAsHtml $html_table `
-SmtpServer 'AMRINT.SMTP.ACCENTURE.COM'
This should work for you. One issue you had is that the variable $dt was never initialized in your script.
param(
$emailFrom = 'Reporting.Services#accenture.com',
$emailTo = 'aditi.m.singh#accenture.com',
$emailSubject = 'Sending the Attachment',
$smtp = 'AMRINT.SMTP.ACCENTURE.COM',
$Server = "$Env:ComputerName\MSSQLSERVER01",
$SQLDBName = 'Master',
$SQLQuery = #"
SELECT Distinct
RL.RoleName,
USR.UserName
FROM
Catalog C
INNER JOIN Policies PL
ON C.PolicyID = PL.PolicyID
INNER JOIN PolicyUserRole PUR
ON PUR.PolicyID = PL.PolicyID
INNER JOIN Users USR
ON PUR.UserID = USR.UserID
INNER JOIN dbo.Roles RL
ON RL.RoleID = PUR.RoleID
WHERE RoleName = 'Content Manager'
ORDER BY USR.UserName
"#
)
# This code connects to the SQL server and retrieves the data
$SQLConnection = New-Object System.Data.SqlClient.SqlConnection
$SqlConnection.ConnectionString = "Server = $Server; Database = $SQLDBName; Integrated Security=true;"
$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()
$data = $DataSet.Tables[0]
$html = $data `
| Select-Object -Property RoleName, UserName `
| ConvertTo-Html -fragment `
| Out-String
Send-MailMessage `
-From $emailFrom `
-To $emailTo `
-Subject $emailSubject `
-BodyAsHtml $html `
-SmtpServer $smtp

SQL Join Query doesn't work in PowerShell

I am trying to convert a Python script into a PS Script. The script reads an access database file and runs a simple query to send the results to a CSV file. The query is executed without problems from Python and also directly from MS Access.
Query:
SELECT
TABLEA.SITE_CODE,
TABLEB.REG_TITLE,
TABLEC.G_ORG_TITLE,
TABLED.BRD_TITLE,
TABLEA.SITE_TYPE
FROM ((TABLEA
LEFT JOIN [TABLEC] ON TABLEA.[G_ORG_ID] = TABLEC.[ID])
LEFT JOIN TABLEB ON TABLEA.[REGION_ID] = TABLEB.[ID])
LEFT JOIN TABLED ON TABLEA.[BRAND_ID] = TABLED.[ID]
ORDER BY TABLEA.SITE_CODE
This is the code that I am using:
$path = "\Path\to\File.mdb"
$QuerySites = "SELECT TABLEA.SITE_CODE, TABLEB.REG_TITLE, TABLEC.G_ORG_TITLE, TABLED.BRD_TITLE, TABLEA.SITE_TYPE FROM ((TABLEA LEFT JOIN [TABLEC] ON TABLEA.[G_ORG_ID] = TABLEC.[ID]) LEFT JOIN TABLEB ON TABLEA.[REGION_ID] = TABLEB.[ID]) LEFT JOIN TABLED ON TABLEA.[BRAND_ID] = TABLED.[ID] ORDER BY TABLEA.SITE_CODE"
$csv = "C:\path\Outfile.csv"
$connection = New-Object -TypeName System.Data.OleDb.OleDbConnection
$connection.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source= $path"
$delimiter = ','
$command2 = $connection.CreateCommand()
$command2.CommandText = $QuerySites
$adapter2 = New-Object -TypeName System.Data.OleDb.OleDbDataAdapter $command2
$dataset2 = New-Object -TypeName System.Data.DataSet
$adapter2.Fill($dataset2)
$connection.Close()
I am getting the following error:
Exception calling "Fill" with "1" argument(s): "IErrorInfo.GetDescription failed with E_FAIL(0x80004005)."
At line:14 char:1
+ $adapter2.Fill($dataset2)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : OleDbException
As I said, the query runs without problems in the Python script and directly from Access.
I have not found resources that guide me to the root cause.
Enclose all of your table and field names in brackets for keyword safety.
SELECT
[TABLEA].[SITE_CODE],
[TABLEB].[REG_TITLE],
[TABLEC].[G_ORG_TITLE],
[TABLED].[BRD_TITLE],
[TABLEA].[SITE_TYPE]
FROM (([TABLEA]
LEFT JOIN [TABLEC] ON [TABLEA].[G_ORG_ID] = [TABLEC].[ID])
LEFT JOIN [TABLEB] ON [TABLEA].[REGION_ID] = [TABLEB].[ID])
LEFT JOIN [TABLED] ON [TABLEA].[BRAND_ID] = [TABLED].[ID]
ORDER BY [TABLEA].[SITE_CODE]

Get count of rows in a partition of an azure table using Azure PowerShell

I would like to get count of rows in a partition. I have the code for getting the total count of rows. How can I alter it to get count for a particular partition. Also I am getting warning for fetching count of all rows and not getting the count on powershell window. Is there any documentation on this?
function GetTable($connectionString, $tableName)
{
$context = New-AzureStorageContext -ConnectionString $connectionString
$azureStorageTable = Get-AzureStorageTable $tableName -Context $context
$azureStorageTable
}
function GetTableCount($table)
{
#Create a table query.
$query = New-Object Microsoft.WindowsAzure.Storage.Table.TableQuery
#Define columns to select.
$list = New-Object System.Collections.Generic.List[string]
$list.Add("PartitionKey")
#Set query details.
$query.SelectColumns = $list
#Execute the query.
$entities = $table.CloudTable.ExecuteQuery($query)
($entities | measure).Count
}
$connectionString = "xyz"
$table = GetTable $connectionString SystemAudit
GetTableCount $table
How can I alter it to get count for a particular partition
There is a function Get-AzureStorageTableRowByPartitionKey you could use, and the following is the sample code
function GetTable($connectionString, $tableName)
{
$context = New-AzureStorageContext -ConnectionString $connectionString
$azureStorageTable = Get-AzureStorageTable $tableName -Context $context
$azureStorageTable
}
function GetTableCount($table)
{
$list = Get-AzureStorageTableRowByPartitionKey -table $table –partitionKey “storage” | measure
$list.Count
}
Import-Module AzureRmStorageTable
$connectionString = xyz"
$table = GetTable $connectionString <yourTableName>
GetTableCount $table
You can know more information on this blog

update sql table for Active Directory createdon and disabled on information

I have a user table in the database that i am trying to update with Createdon date and disabled on date with the data from Active Directory. So far this is what I have:
$SearchRoot = "OU=NonAIQ,OU=FrontOffice,DC=dev,DC=local"
$serverName = "localhost"
#$SearchRoot = "OU=NonAIQ,OU=FrontOffice,DC=dmz,DC=local"
#$serverName = "spoproddb3.dmz.local"
try {
Import-Module "sqlps" -DisableNameChecking
if ((Get-PSSnapin -Name "Quest.ActiveRoles.ADManagement" -ErrorAction SilentlyContinue) -eq $null ) {
Add-PsSnapin "Quest.ActiveRoles.ADManagement"
}
$externalUsers = Get-QADUser -SizeLimit 0 -SearchRoot $SearchRoot | Select-Object whencreated, whenchanged
$externalUsers | % {
$query = #"
Update tbl_EdgeUsers Set CompanyName = '$_.CreationDate'
Where UserUPN = $_.UserPrincipalName;
"#
Write-Host "The query is $query"
Invoke-SqlCmd -ServerInstance $serverName -Query $query -Database "EdgeDW"
}
} finally {
Remove-Module "sqlps" -ErrorAction SilentlyContinue
Remove-PsSnapin "Quest.ActiveRoles.ADManagement"
}
Now for when created, we just grab all the values.
But since AD does not track the Disabled in date, I am using the when changed date since we dont make changes to an account once it is changed.
The part that I am stuck on is about the logic for when changed date. For this I have to check if an account is disabled. If it is the update the table with that date. If an account is not disabled, then ignore that value and set the value in the sql table as '1/1/9999'.
can you guys please help with this logic?
Thank you in advance for any help.
of top of my head maybe something such as this, although thinking about it now, its a nasty way having the invoke-sql inside the foreach loop if the dataset is large, probably better to output the results of the if statement to csv or somewhere then run the invoke-sql against that.
$users = Get-ADUser -Filter * -Properties whenchanged | Select-Object -Property UserPrincipalName, whenchanged, enabled
$disabledsql = #"
update tbl_EdgeUsers Set date = '$user.whenchanged'
Where UserUPN = '$user.UserPrincipalName';
"#
$activesql = #"
update tbl_EdgeUsers Set date = '1/1/9999
Where UserUPN = '$user.UserPrincipalName';
"#
foreach ($user in $users)
{
if ($user.enabled -eq 'False')
{
Invoke-Sqlcmd -ServerInstance $serverName -Query $disabledsql -Database 'EdgeDW'
}
else
{
Invoke-Sqlcmd -ServerInstance $serverName -Query $activesql -Database 'EdgeDW'
}
}