Programatically Get ADF pipeline consumption report - azure

I'm interested in querying the pipeline consumption report that is available from the Data Factory monitor. Is there a table on Log Analytics or PowerShell cmdlet that would return this information? I checked the ADFv2 PowerShell module but couldn't find any. My goal is to aggregate the information available in this report to identify what are the most costly pipelines.
reference: https://techcommunity.microsoft.com/t5/azure-data-factory/new-adf-pipeline-consumption-report/ba-p/1394671
Thank you

Doing more research someone pointed me to a GitHub page where the product team posted a PowerShell script to find part of what I was looking for {1}. So I did some modifications to the script to have the output that I needed. With the output below I can extract the values from the MS calculator to get an estimated cost for each pipeline run. {2}
$startTime = "21/6/2021 7:00:00"
$endTime = "21/6/2021 10:00:00"
$adf = '<data factory name>'
$rg = '<resrouce group name>'
$outputObj = #()
$pipelineRuns = Get-AzDataFactoryV2PipelineRun -ResourceGroupName $rg -DataFactoryName $adf -LastUpdatedAfter $startTime -LastUpdatedBefore $endTime
# loop through all pipelines and child activities to return billable information
foreach ($pipelineRun in $pipelineRuns) {
$activtiyRuns = Get-AzDataFactoryV2ActivityRun -ResourceGroupName $rg -DataFactoryName $adf -pipelineRunId $pipelineRun.RunId -RunStartedAfter $startTime -RunStartedBefore $endTime
foreach ($activtiyRun in $activtiyRuns) {
if ($null -ne $activtiyRun.Output -and $null -ne $activtiyRun.Output.SelectToken("billingReference.billableDuration")) {
$obj = #()
$obj = $activtiyRun.Output.SelectToken("billingReference.billableDuration").ToString() | ConvertFrom-Json
$obj | Add-Member -MemberType NoteProperty -Name activityType -value $activtiyRun.Output.SelectToken("billingReference.activityType").ToString()
$obj | Add-Member -MemberType NoteProperty -Name pipelineName -value $pipelineRun.PipelineName
$obj | Add-Member -MemberType NoteProperty -Name activtiyRuns -value $activtiyRuns.Count
$outputObj += $obj
}
else {}
}
}
# output aggregated result set as table
$groupedObj = $outputObj | Group-Object -Property pipelineName, activityType, meterType
$groupedObj | ForEach-Object {
$value = $_.name -split ', '
New-Object psobject -Property #{
activityType = $value[1];
meterType = $value[2];
pipelineName = $value[0];
executionHours = [math]::Round(($_.Group | Measure-object -Property duration -sum).Sum, 4)
orchestrationActivityRuns = $groupedObj.group.activtiyRuns[0]
}
} | Sort-Object -Property meterType | Format-Table
Output sample:
Consumption report from the Data Factory monitor
reference:
https://github.com/Azure/Azure-DataFactory/tree/main/SamplesV2/PastRunDetails#simple-script-that-prints--activity-level-run-details-in-45-day-range {1}
https://azure.microsoft.com/en-us/pricing/calculator/?service=data-factory%2F {2}

Related

How to split different values in powershell by a line

With this script i am able to fetch all the Tags that a VM has but i want that in output the each key and its value should be separated by a line in the way that each key and its value appears on different lines like this
reference image
# Sign into Azure Portal
connect-azaccount
# Fetch the Virtual Machines from the subscription
$azureVMDetails = get-azvm
# Fetch the NIC details from the subscription
$azureNICDetails = Get-AzNetworkInterface | ?{ $_.VirtualMachine -NE $null}
#Fetching Virtual Machine Details
$virtual_machine_object = $null
$virtual_machine_object = #()
#Iterating over the NIC Interfaces under the subscription
foreach($azureNICDetail in $azureNICDetails){
#Fetching the VM Name
$azureVMDetail = $azureVMDetails | ? -Property Id -eq $azureNICDetail.VirtualMachine.id
#Fetching the VM Tags
foreach($azureDetail in $azureVMDetails) {
$vm_tags = $azureVMDetail| Select-Object -Property (
#{name='Tags'; expression = {($_.tags.GetEnumerator().ForEach({ '{0} : {1}' -f $_.key, $_.value }) -join ';')}}
)
}
#VM Details export
$virtual_machine_object_temp = new-object PSObject
$virtual_machine_object_temp | add-member -membertype NoteProperty -name "name" -Value $azureVMDetail.Name
$virtual_machine_object_temp | add-member -membertype NoteProperty -name "comments" -Value ($vm_tags.Tags -join ';')
$virtual_machine_object += $virtual_machine_object_temp
}
#Report format and path
$virtual_machine_object | Export-Csv "C:\Users\JOHN\Desktop\Inventory\Final Scripts\VM_details_$(get-date -f dd.MM.yyyy).csv" -NoTypeInformation -Force
I tried to reproduce the same in my environment and got the results successfully by using the below PowerShell script:
$vmdeatil = Get-AzVm -Name testvm | Select -ExpandProperty Tags
$value = $vmdeatil
foreach($i in 0..($value.Count -1))
{
$ErrorActionPreference = ‘SilentlyContinue’
[array]$report += [pscustomobject] #{
key = $key[$i]
name = $value[$i]
}
}
$report | Export-Csv -Path "C:\Users\ruk1.csv" -NoTypeInformation
Response:
The output is successfully exported in the csv file like below:

how to use if/else statement to replace a value in PowerShell

function Get-vmstatus {
# Sign into Azure Portal
connect-azaccount
# Fetch the Virtual Machines from the subscription
$azureVMDetails = get-azvm
# Fetch the NIC details from the subscription
$azureNICDetails = Get-AzNetworkInterface | ? { $_.VirtualMachine -NE $null }
#Fetching Virtual Machine Details
$virtual_machine_object = $null
$virtual_machine_object = #()
#Iterating over the NIC Interfaces under the subscription
foreach ($azureNICDetail in $azureNICDetails) {
$azureVMDetail = $azureVMDetails | ? -Property Id -eq $azureNICDetail.VirtualMachine.id
$vm_status = get-azvm -ResourceGroupName $azureVMDetail.resourcegroupname -name $azureVMDetail.name -Status
$vm_tags = ($azureVMDetail.Tags.values) -join ';'
$vmsize = Get-AzVMSize -VMName $azureVMDetail.Name -ResourceGroupName $azureVMDetail.ResourceGroupName | ? { $_.Name -eq $azureVMDetail.HardwareProfile.VmSize }
$OsDisksize = $azureVMDetail.StorageProfile.OsDisk.DiskSizeGB
#Fetching the private IP
$private_ip_address = ($azureNICDetail.IpConfigurations | select-object -ExpandProperty PrivateIpAddress) -Join ';'
#VM Details export
$virtual_machine_object_temp = new-object PSObject
$virtual_machine_object_temp | add-member -membertype NoteProperty -name "Name" -Value $azureVMDetail.Name
$virtual_machine_object_temp | add-member -membertype NoteProperty -name "VCPUs" -Value $vmsize.NumberOfCores
$virtual_machine_object_temp | add-member -membertype NoteProperty -name "Status" -Value $vm_status.Statuses[1].DisplayStatus
$virtual_machine_object_temp | add-member -membertype NoteProperty -name "Memory" -Value $vmsize.MemoryInMB
$virtual_machine_object_temp | add-member -membertype NoteProperty -name "Disk" -Value $OsDisksize
$virtual_machine_object_temp | add-member -membertype NoteProperty -name "Comments" -Value $vm_tags
$virtual_machine_object += $virtual_machine_object_temp
}
$virtual_machine_object | Export-Csv "C:\Users\mouj\Desktop\Inventory\Final Scripts\VM_details_$(get-date -f dd.MM.yyyy).csv" -NoTypeInformation -Force
}
After running the script the Status of the Azure VMs are shown as VM running, VM stopped, VM deallocated. Now i want to replace the VM running with "Active" and VM stopped, VM deallocated with "Offline". How can i do with conditional statement or is there any other way to do it ? Thanks in advance
Use Add-Member to add a ScriptProperty - a dynamic property that can reference the value(s) of other properties on the object:
$virtual_machine_object_temp | Add-Member -MemberType ScriptProperty -Name State -Value { if($_.Status -eq 'Running'){ 'Active' }else{ 'Offline' } }
Now, whenever you look at the new State property, it will resolve to Active whenever the Status property is Running, otherwise Offline

Compiling data into columns to be exported to CSV/excel

I am writing a short script to inventory all servers in our infrastructure, this used to be done manually which means some servers may show up as active in our SQL DB but is actually offline, or vice versa.
What i want to do is query our vCenter, SQL and AD and then compiling the result into a csv to be viewed in Excel (see pic ) http://imgur.com/NnwEM4H
Now here is my question: How do i add the columns and format this properly? I want a seperate row for each servername which means sometimes that row will be a blank/empty in one or more of the columns. The Refrence list will always contain a servername though.
I've tried the following:
$ServerList = #()
foreach ($p in $RefList)
{
$Server = New-Object System.Object
$Server | Add-Member -MemberType NoteProperty -Name RefrenceList -Value $p.Name
$ServerList += $Server
}
foreach ($s in $VMList)
{
$Server = New-Object System.Object
$Server | Add-Member -MemberType NoteProperty -Name vCenter -Value $s.name
$ServerList += $Server
}
Which doesnt create the vCenter column or add any data to it.
I also asked over at reddit/r/powershell and tried the following, which unfortently doesn't work either:
$ServerList = #()
foreach ($p in $RefList)
{
$Server = New-Object System.Object
$Server | Add-Member -MemberType NoteProperty -NameRefrenceList -Value $p.Name
$ServerList += $Server
}
Foreach ($server in $serverlist)
{
if ($vmlist -contains $server)
{
$server | add-member -MemberTypeNoteProperty -Name VMList -Value $Server
}
}
I'm at a loss here, i can't even get the first 2 columns to work..
Any advice i greatly appriceiated
First build the List will all Noteproperties :
$ServerList = $reflist | select Name, SQL,SCCM, AD, VCenter #as needed.
Now you can easily update the fields with your foreach Statements.
foreach ($server in $ServerList)
{
if ($vmlist -contains $server)
{
$Server.VCenter = $Server.Name
}
if ($sqllist -contains $server)
{
$Server.SQL = $Server.Name
}
#....
}
and so on with your other lists.

Object within a hashtable

I'm trying to put objects in a hashtable. I'm not getting errors but cannot access the data.
$Level1Hashtable = #{}
$Level2Object = New-Object System.Object
$Level2Object | Add-Member -MemberType NoteProperty -Name Name -Value "abc"
$Level2Object | Add-Member -MemberType NoteProperty -Name IpAddress -Value "192.168.1.1"
$Level1Hashtable.Add("Test1",$Level2Object)
$Level2Object = New-Object System.Object
$Level2Object | Add-Member -MemberType NoteProperty -Name Name -Value "123"
$Level2Object | Add-Member -MemberType NoteProperty -Name IpAddress -Value "192.168.1.1"
$Level1Hashtable.Add("Test2",$Level2Object)
$Level1Hashtable.Test1.IpAddress
This kind of redundant instantiation doesn't really impress me, so I went a slightly different route:
$Servers =
#{
"DC1" = [pscustomobject]#{ FQDN = "dc1.ad.foobar.com"; IpAddress = "192.168.2.1"}
"DC2" = [pscustomobject]#{ FQDN = "dc2.ad.foobar.com"; IpAddress = "192.168.2.2"}
"STS" = [pscustomobject]#{ FQDN = "sts.ad.foobar.com"; IpAddress = "192.168.2.3"}
}
Then you can also access elements very easily:
Servers["DC1"].IpAddress = "192.168.2.4"
Tested on PowerShell Core (aka PowerShell 6), works like a charm. Cheers.
That works for me using V4. Running in V2 it doesn't work, but does if I switch from using System.Object to PSObject for the object type in the New-Object cmdlets.
$Level1Hashtable = #{}
$Level2Object = New-Object PSObject
$Level2Object | Add-Member -MemberType NoteProperty -Name Name -Value "abc"
$Level2Object | Add-Member -MemberType NoteProperty -Name IpAddress -Value "192.168.1.1"
$Level1Hashtable.Add("Test1",$Level2Object)
$Level2Object = New-Object PSObject
$Level2Object | Add-Member -MemberType NoteProperty -Name Name -Value "123"
$Level2Object | Add-Member -MemberType NoteProperty -Name IpAddress -Value "192.168.1.1"
$Level1Hashtable.Add("Test2",$Level2Object)
$Level1Hashtable.Test1.IpAddress
Depending on the version of PowerShell you're using Add-Member had an issue (v1 and maybe v2) where you had to use -PassThru and reassign to the original object e.g.:
$Level2Object = $Level2Object | Add-Member NoteProperty Name abc -PassThru
In V3 you can create this more simply like so:
$Level2Object = [pscustomobject]#{Name='abc';IpAddress='192.168.1.1'}
In V2 you can use the Property parameter on new-object to simplify as well:
$Level2Object = new-object psobject -property #{Name='abc';IpAddress='192.168.1.1'}

Using PowerShell's Add-Member results in an error

Why does the script below come up with the following error?
"Add-Member : Cannot process command because of one or more missing
mandatory parameters: InputObject.
+ $obj = Add-Member <<<< -MemberType NoteProperty -Name ComputerName -Value $ComputerName
+ CategoryInfo : InvalidArgument: (:) [Add-Member], ParameterBindingException
+ FullyQualifiedErrorId : MissingMandatoryParameter,Microsoft.PowerShell.Commands.AddMemberCommand"
Script
# Receives the computer name and stores the required results in $obj.
Function WorkerNetworkAdaptMacAddress {
Param($ComputerName)
$colItems = GWMI -cl "Win32_NetworkAdapterConfiguration" -name "root\CimV2" -comp $ComputerName -filter "IpEnabled = TRUE"
$obj = New-Object -TypeName PSobject
ForEach ($objItem in $colItems)
{
$obj = Add-Member -MemberType NoteProperty -Name ComputerName -Value $ComputerName
$obj = Add-Member -MemberType NoteProperty -Name MacAddress -Value $objItem.MacAddress
$obj = Add-Member -MemberType NoteProperty -Name IPAdress -Value $objitem.IpAddress
}
Write-Output $obj
}
# Receives the computer name and passes it to WorkerNetworkAdaptMacAddress.
Function Get-NetworkAdaptMacAddress {
begin {}
process{
WorkerNetworkAdaptMacAddress -computername $_
}
end {}
}
# Passes a computer name to get-networkAdaptMacAddress
'tbh00363' | Get-NetworkAdaptMacAddress
You need to move the PSObject creation into the loop. Otherwise, you'll get errors that the properties already exist on the object.
Secondly, you need to tell Add-Member on which object to operate. You do it either by piping the object to the cmdlet or by specifying it on the InputObject parameter. Finally, return the object back to the pipeline by specifying the PassThru switch on the last Add-Member call:
ForEach ($objItem in $colItems)
{
$obj = New-Object -TypeName PSobject
Add-Member -InputObject $obj -MemberType NoteProperty -Name ComputerName -Value $ComputerName
Add-Member -InputObject $obj -MemberType NoteProperty -Name MacAddress -Value $objItem.MacAddress
Add-Member -InputObject $obj -MemberType NoteProperty -Name IPAddress -Value $objitem.IpAddress -PassThru
}
Alternatively, you could simplify the process with New-Object's -Property parameter:
Get-WmiObject Win32_NetworkAdapterConfiguration -ComputerName $ComputerName -Filter "IpEnabled=TRUE" | Foreach-Object {
New-Object -TypeName PSobject -Property #{
ComputerName=$ComputerName
MacAddress=$_.MacAddress
IPAddress=$_.IpAddress
}
}
Or by using Select-Object:
Get-WmiObject ... | Select-Object #{n='ComputerName';e={$_.__SERVER}},MacAddress,IpAddress
First you need to specify the input object to which the property should be added by piping it to the Add-Member cmdlet.
Then, if you want the cmdlet to return the modified object, you should invoke it with the -PassThru argument:
When you use the PassThru parameter, Add-Member returns the
newly-extended object. Otherwise, this cmdlet does not generate any
output.
Here's a slightly modified version of your script:
$obj = $objItem | Add-Member -MemberType NoteProperty -Name ComputerName -Value $ComputerName -PassThru
However, since in your case you don't really need to save the output object in a new variable, you could also simply say:
$obj | Add-Member -MemberType NoteProperty -Name ComputerName -Value $ComputerName
Try like this:
$objcol = #()
ForEach ($objItem in $colItems)
{
$obj = New-Object System.Object
$obj | Add-Member -MemberType NoteProperty -Name ComputerName -Value $ComputerName
$obj | Add-Member -MemberType NoteProperty -Name MacAddress -Value $objItem.MacAddress
$obj | Add-Member -MemberType NoteProperty -Name IPAdress -Value $objitem.IpAddress
$objcol += $obj
}
Write-Output $objcol
As indicated by Enrico, Shay and Christian, you should specify the object on which Add-Member operates, either by piping the object to Add-Member or by explicitly specifying the object on the InputObject parameter. When adding multiple members using Add-Member I usually add the PassThru switch to avoid repeating the InputObject and to provide a visual cue.
ForEach ($objItem in $colItems) {
$obj = New-Object PSobject
$obj | Add-Member -MemberType NoteProperty -Name ComputerName -Value $ComputerName -PassThru `
| Add-Member -MemberType NoteProperty -Name MacAddress -Value $objItem.MacAddress -PassThru `
| Add-Member -MemberType NoteProperty -Name IPAdress -Value $objitem.IpAddress -PassThru
}
You're assigning the result of Add-Member to a variable, not adding it to a property collection within $obj.
Instead of
$obj = Add-Member -MemberType NoteProperty -Name ComputerName -Value $ComputerName
Try this:
Add-Member -MemberType NoteProperty -Name ComputerName -Value $ComputerName -inputObject $obj

Resources