Powershell - Import seperate array values to columns - sql

I'm very new to Powershell, and I'm trying to extract data from Teams (using the Graph API ) I have successfully exported the required data into an SQL table (using the Invoke-Sqlcmd function )
When extracting the users involved on the call, I get the CallID but the participant values are placed in a single field
CallID Participants
CallGUID-xxxx-xxxx-xxxx-xxxxxxxxxx John Smith Mary Brown Billy Dee Williams
and I need to format it like below
CallID Participants
CallGUID-xxxx-xxxx-xxxx-xxxxxxxxxx John Smith
CallGUID-xxxx-xxxx-xxxx-xxxxxxxxxx Mary Brown
CallGUID-xxxx-xxxx-xxxx-xxxxxxxxxx Billy Dee Williams
The code I am using is below.
$clientId = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
$clientSecret = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
$tenantName = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
$tenantName = "xxxxxxxx.onmicrosoft.com"
$resource = "https://graph.microsoft.com/"
$tokenBody = #{
Grant_Type = "client_credentials"
Scope = "https://graph.microsoft.com/.default"
Client_Id = $clientId
Client_Secret = $clientSecret
}
$URL = "https://graph.microsoft.com/v1.0/communications/callRecords/CallGUID-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
$tokenResponse = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$TenantName/oauth2/v2.0/token" -Method POST -Body $tokenBody
$response = Invoke-RestMethod -Headers #{Authorization = "Bearer $($tokenResponse.access_token)"} -Uri $URL
$CallDetailsID = $response.id
$CallDetailsStart = $response.startDateTime
$CallDetailsEnd = $response.endDateTime
$CallDetailsParticipants = $response.Participants.user.displayname
Invoke-Sqlcmd -Query "INSERT INTO [Alpha].[dbo].[Table] (CallID, Participants) SELECT '$CallGUID', $CallDetailsParticipants)" -ServerInstance "Server\Instance"
Is anyone able to help point out what I am doing wrong?

Looks like you need to loop over each participant to insert them individually.
Try
$qry = "INSERT INTO [Alpha].[dbo].[Table] (CallID, Participants) SELECT '$CallGUID', '{0}'"
foreach ($participant in $CallDetailsParticipants) {
Invoke-Sqlcmd -Query ($qry -f $participant) -ServerInstance "Server\Instance"
}
(edited by OP after testing)

Related

Powershell mail every user from SQL query

Unfortunately, I could not find my answer from all the examples I came across.
I have a SQL query that contains the following values
First name
Suffix
Last Name
Email address
Now I want to send a mail per record and in the mail mention the name.
Below is the code that doesn't do the loop right now and puts the name in the mail.
<# Variabelen #>
$PlaceDate = "Amsterdam, " + (Get-Date -f dd-MM-yyyy)
$MailSubject = "My subject"
$sqlinstance = "MSSQLSRV1"
<# SQL data #>
$query = "SELECT [Firstname]
,[Suffix]
,[Lastname]
,[Emailaddress]
,[DateVisit]
FROM [DBname].[dbo].[tbl_EventVisitors]
where CONVERT(DATE, [DateVisit]) = CAST( GETDATE()-1 AS Date )"
$results = Invoke-Sqlcmd -Query $query -ServerInstance $sqlinstance
<# Create mail with SQL fields #>
$CoryReportHtml = ConvertTo-Html -PreContent #"
<body>
<br />
$PlaceDate<br /><br />
Dear $Firstname $Suffix $Lastname,<br />
MyMessage
</body>
"# | Out-String
<# Send the mail #>
$mailParams = #{
SmtpServer = 'localhost'
to = $Emailaddress
from = "from#example.com"
Subject = $MailSubject
Body = $CoryReportHtml
BodyAsHtml = $true
}
Send-MailMessage #mailParams
$results = Invoke-Sqlcmd -Query $query -ServerInstance $sqlinstance
foreach ($row in $results) {
$body_value = $null
$body_value = "Dear $($row.Firstname) $($row.$Lastname)"
$body_value += "my message"
$Emailaddress = $row.Name
$MailSubject = "Subject here"
$mailParams = #{
SmtpServer = 'localhost'
to = $Emailaddress
from = "from#example.com"
Subject = $MailSubject
Body = $body_valu
BodyAsHtml = $true
}
Send-MailMessage #mailParams
Write-Host "email sent to $row.name"
}

Multi-level json to SQL outputs per element instead of per row

I'm using the Microsoft 365 Defender API to receive all recent events/incidents.
I get a json file as following: link to example json
And use following script to try and convert this for easy import to an SQL server:
(Echoes only as test)
# Send the request and get the results.
$response = Invoke-WebRequest -UseBasicParsing -Method Get -Uri $url -Headers $headers -ErrorAction Stop
# Extract the incidents from the results.
$alerts = ($response | ConvertFrom-Json)
$devices = ($response | ConvertFrom-Json ).value.alerts.devices
$entities = ($response | ConvertFrom-Json ).value.alerts.entities
Foreach($row in $alerts){
$IncidentID = $alerts.value.incidentID
$Createdtime = $alerts.value.creationTime
$Status = $alerts.value.status
$Severity = $alerts.value.severity
$Classification = $alerts.value.classification
$IncidentName = $alerts.value.incidentName
$URL = $alerts.incidentUri
$Klant = $afkorting
$Username = $entities.accountname
$device = $devices.deviceDnsName
echo $IncidentID
echo $Createdtime
echo $Status
echo $Severity
echo $Classification
echo $IncidentName
echo $URL
echo $Klant
echo $Username
echo $device
Invoke-Sqlcmd -ServerInstance "SQL.domain.local\MSQL2016" -Database "private" -Username private -Password 'private' -Query "INSERT Into dbo.private ( [IncidentID], [Createdtime], [Status], [Severity], [Classification], [IncidentName], [URL], [Klant], [Username], [device]) VALUES ('$IncidentID', '$Createdtime', '$Status', '$Severity', '$Classification', '$IncidentName', '$URL', '$Klant', '$Username', '$device')"
}
However, the output in case of 3 incidents looks like:
IncidentID
IncidentID
IncidentID
Createdtime
Createdtime
Createdtime
Status
Status
Status
So grouped by element instead of grouped by IncidentID.
I can't find a way to get the output like:
IncidentID
Createdtime
Status
Severity
Classification
IncidentName
URL
Klant
Username
device
I "solved" this with an intermediary step exporting to CSV's and merging them and piping those to SQL for now, but that's too inefficient.
Move resolution of $devices and $entities into the loop, then use the iterator variable $row instead of referencing all $alerts inside the loop body:
# Send the request and get the results.
$response = Invoke-WebRequest -UseBasicParsing -Method Get -Uri $url -Headers $headers -ErrorAction Stop
# Extract the incidents from the results.
$alerts = ($response | ConvertFrom-Json)
foreach($row in $alerts){
$IncidentID = $row.value.incidentID
$Createdtime = $row.value.creationTime
$Status = $row.value.status
$Severity = $row.value.severity
$Classification = $row.value.classification
$IncidentName = $row.value.incidentName
$URL = $row.incidentUri
$Klant = $afkorting # where does `$afkorting` come from?
$Username = $row.value.entities.accountname
$device = $row.value.devices.deviceDnsName
# Insert into SQL Server here
}

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'
}
}

PHP Magento API catalog_product.info not working when running through a list

I am trying to create a magento API to get the pricing of each item. I have a table with all the SKU's i need to get info for. i ran the following for one item and it worked
$client = new SoapClient('http://www.mysite.com/api/soap/?wsdl');
$session = $client->login('user', 'pass');
$productId = 'ABC';
$att = array("visibility","sku","special_price", "price");
$arguments = array( $productId, NULL, $att);
$result = $client->call($session, 'catalog_product.info', $arguments);
echo $result['visibility'].",".$result['sku'].",".$result['special_price'].",".$result['price'];
the above code worked fine.
then i tested another code to make sure that my code to query the database and loop through each sku works
$getskus = "SELECT sku FROM items;";
$skus = mysqli_query($con, $getskus);
while($row = mysqli_fetch_array($skus))
{
$productId = $row['sku'];
echo $productId."<br>";
}
The above code works fine. My issue is when i combine the 2 i get a blank screen.
$client = new SoapClient('http://www.mysite.com/api/soap/?wsdl');
$session = $client->login('user', 'pass');
$getskus = "SELECT sku FROM items;";
$skus = mysqli_query($con, $getskus);
while($row = mysqli_fetch_array($skus))
{
$productId = $row['sku'];
$att = array("visibility","sku","special_price", "price");
$arguments = array( $productId, NULL, $att);
$result = $client->call($session, 'catalog_product.info', $arguments);
echo $result['visibility'].",".$result['sku'].",".$result['special_price'].",".$result['price'];
}
i get nothing. Any ideas?
update: if $row['sku'] = '9005' will magento think its a product id instead of a SKU?
This line:
$result = $client->call($session, 'catalog_product.info', $arguments);
This can't accept $arguments as the third param. Instead:
$result = $client->call($session, 'catalog_product.info', $row['sku'], null, $att, 'sku');
NB: not sure if 'null' (4th param) is a valid argument for store view. To be safe, replace with the correct store view (default, in most cases).
RTM: http://www.magentocommerce.com/api/soap/catalog/catalogProduct/catalog_product.info.html