Wednesday 25 May 2022

Create a Json file from string object using PowerShell

 Hi Readers,

We will see in this post on how we can create a Json object and save it to a Json file using PowerShell. 

Let's take a very simple Json example. The below section will generate a Json file via PowerShell that looks like below
{
    "Name":  "Student01",
    "Class":  "2",
    "Gender":  "Male"
}

Create a string object. You may want to do it dynamically based on your requirement. I have taken a hard-coded string here for simplicity purpose.
Convert string object to a PSCustomObject using ConvertFrom-Json and then convert it back to Json string using ConvertTo-Json and save it in a Json file.
The code in PowerShell will look like this.
$mySimpleJsonstring = "{Name:'Student01',Class:'2',Gender:'Male'}"

$mySimplePSCustomObject = $mySimpleJsonstring | ConvertFrom-Json
$mySimpleJsonContent = $mySimplePSCustomObject | ConvertTo-Json 
$mySimpleJsonContent > mySimpleJsonContent.json
When you will run above script. It will generate "mySimpleJsonContent.json" file which will look like below






Let's take another example of a complex Json. The generated Json file should have Json like below
[
    {
        "TargetType":  "Fruit",
        "TargetId":  [
                         "98e422be-d613-48e3-8453-16d2107ac77a"
                     ],
        "TargetMetadata":  {
                               "Type":  "Citrus Fruit",
                               "Name":  "Lemon"
                           }
    },
    {
        "TargetType":  "Vegetable",
        "TargetId":  [
                         "hde422be-d613-48e3-8453-16d2107ac77a"
                     ],
        "TargetMetadata":  {
                               "Type":  "Leafy Vegetable",
                               "Name":  "Coriander"
                           }
    }
]

The PowerShell script will look like this, and it will generate a "myComplexJsonContent.json" file. You will need to create the string object dynamically based on your requirement. I have taken a hard-coded string here for simplicity purpose.
$myComplexJsonString = 
"[{
  TargetType: 'Fruit',
  TargetId: ['98e422be-d613-48e3-8453-16d2107ac77a'],
  TargetMetadata: {'Type': 'Citrus Fruit', 'Name': 'Lemon'}
},
{
  TargetType: 'Vegetable',
  TargetId: ['hde422be-d613-48e3-8453-16d2107ac77a'],
  TargetMetadata: {'Type': 'Leafy Vegetable', 'Name': 'Coriander'}
}]"

$myComplexPSCustomObject = $myComplexJsonString | ConvertFrom-Json
$myComplexJsonContent = $myComplexPSCustomObject | ConvertTo-Json 
$myComplexJsonContent > myComplexJsonContent.json










This is the full PowerShell script for both the examples.
$mySimpleJsonstring = "{Name:'Student01',Class:'2',Gender:'Male'}"

$mySimplePSCustomObject = $mySimpleJsonstring | ConvertFrom-Json
$mySimpleJsonContent = $mySimplePSCustomObject | ConvertTo-Json 
$mySimpleJsonContent > mySimpleJsonContent.json


$myComplexJsonString = 
"[{
  TargetType: 'Fruit',
  TargetId: ['98e422be-d613-48e3-8453-16d2107ac77a'],
  TargetMetadata: {'Type': 'Citrus Fruit', 'Name': 'Lemon'}
},
{
  TargetType: 'Vegetable',
  TargetId: ['hde422be-d613-48e3-8453-16d2107ac77a'],
  TargetMetadata: {'Type': 'Leafy Vegetable', 'Name': 'Coriander'}
}]"

$myComplexPSCustomObject = $myComplexJsonString | ConvertFrom-Json
$myComplexJsonContent = $myComplexPSCustomObject | ConvertTo-Json 
$myComplexJsonContent > myComplexJsonContent.json
Let me know if this blog was helpful to you ðŸ™‚ Happy Scripting!!!

Friday 2 July 2021

Convert Specific Table of Excel Sheet to JSON



There is an excellent script available on GitHub which helps in converting an excel sheet to JSON. The table which it converts to JSON is from the start of the page i.e. from A1 cell (as shown in image below).

I had a little different requirement. I had to convert a specific table among various tables available within a sheet in an excel file as shown in image below.

In example given above, there are multiple sheets within an excel file. The sheet that I am interested in is “Science”. Inside Science sheet there are multiple tables like Class1, Class2 …. Class 10 and so on. And I am interested in finding out Class 6 students data which is at row 44. Header is at row 45 and data starts from row 46. The tables can be at any location (any column and any row) within the sheet. The only identifier I am using is TableName which is “Class 6” in this example.

And this is how I have achieved it -

Input Parameters

The script accepts 3 parameters

$InputFileFullPath: - This is path of input excel file. Example - "C:\Data\ABCDSchool.xlsx"

$SubjectName: - This is name of the sheet inside excel file. Example - "Science"

$ClassName: -This is name of the table within excel sheet. Example - "Class 6"

#Inputs
$InputFileFullPath = "C:\Data\ABCDSchool.xlsx"
$SubjectName = "Science"
$ClassName = "Class 6"

Open excel file and read the “Science” sheet

$excelApplication = New-Object -ComObject Excel.Application
$excelApplication.DisplayAlerts = $false
$Workbook = $excelApplication.Workbooks.Open($InputFileFullPath)

$sheet = $Workbook.Sheets | Where-Object {$_.Name -eq $SubjectName}
if (-not $sheet) {
    throw "Could not find subject '$SubjectName' in the workbook"
}

Grab “Class 6” table within “Science” sheet to work with

$found = $sheet.Cells.Find($ClassName) #find the cell where Class name is mentioned
$beginAddress = $Found.Address(0,0,1,1).Split("!")[1]
$beginRowAddress = $beginAddress.Substring(1,2)
$startHeaderRowNumber = [int]$beginRowAddress + 1 #header row starts 1 row after the class name 
$startDataRowNumber = $startHeaderRowNumber + 1 #student data row starts 1 rows after header row
$beginColumnAddress = $beginAddress.Substring(0,1)
$startColumnHeaderNumber = [BYTE][CHAR]$beginColumnAddress - 65 + 1 #ASCII number of column

Extract Header Columns Name (Logical Seat Location, Actual Seat Location, LAN Port #, Monitor Cable Port, Student Name, Student#, Room Type)

$Headers = @{}
$numberOfColumns = 0
$foundHeaderValue = $true
while ($foundHeaderValue -eq $true) {
    $headerCellValue = $sheet.Cells.Item($startHeaderRowNumber, $numberOfColumns+$startColumnHeaderNumber).Text 
    if ($headerCellValue.Trim().Length -eq 0) {
        $foundHeaderValue = $false
    } else {
        $numberOfColumns++
        if($Headers.ContainsValue($headerCellValue))
        {
            #do not add any duplicate column again.
        }
        else
        {            
            $Headers.$numberOfColumns = $headerCellValue
        }
    }
}

Extract Data Rows (Class 6 Student Information Rows)

$results = @()
$rowNumber = $startDataRowNumber
$finish = $false
while($finish -eq $false)
{
    if ($rowNumber -gt 1) {
        $result = @{}        
        foreach ($columnNumber in $Headers.GetEnumerator()) {
            $columnName = $columnNumber.Value
            $cellValue = $sheet.Cells.Item($rowNumber, $columnNumber.Name+($startColumnHeaderNumber-1)).Value2 # student data row, student data column number
            if($cellValue -eq $null)
            {
                $finish = $true
                break;
            }
            $result.Add($columnName.Trim(),$cellValue.Trim())
        }
        if($finish -eq $false)
        {
            $result.Add("RowNumber",$rowNumber) #adding excel sheet row number for validation        
            $results += $result
            $rowNumber++
        }
    }
}

Create JSON file and close excel file

$inputFileName = Split-Path $InputFileFullPath -leaf
$jsonOutputFileName = "$($inputFileName.Split(".")[0])-$SubjectName-$ClassName.json"
$jsonOutputFileFullPath = [System.IO.Path]::GetFullPath($jsonOutputFileName) #Output file name will be "ABCDSchool-Science-Class 6.json" 


Write-Host "Converting sheet '$SubjectName' to '$jsonOutputFileFullPath'"
$ignoreOutput = $results | ConvertTo-Json | Out-File -Encoding ASCII -FilePath $jsonOutputFileFullPath
$ignoreOutput = $excelApplication.Workbooks.Close()
$ignoreOutput = [void][System.Runtime.InteropServices.Marshal]::ReleaseComObject($excelApplication) 
Full code goes like this
param 
(
    [Parameter(Mandatory=$true)]
    [string]$InputFileFullPath, #excel name
    [Parameter(Mandatory=$true)]
    [string]$SubjectName, #sheet name
    [Parameter(Mandatory=$true)]
    [string]$ClassName #identifier for the table
)

#open excel file
$excelApplication = New-Object -ComObject Excel.Application
$excelApplication.DisplayAlerts = $false
$Workbook = $excelApplication.Workbooks.Open($InputFileFullPath)

#find sheet
$sheet = $Workbook.Sheets | Where-Object {$_.Name -eq $SubjectName}
if (-not $sheet) {
    throw "Could not find subject '$SubjectName' in the workbook"
}

#grab the table within sheet to work with
$found = $sheet.Cells.Find($ClassName) #find the cell where Class name is mentioned
$beginAddress = $Found.Address(0,0,1,1).Split("!")[1]
$beginRowAddress = $beginAddress.Substring(1,2)
$startHeaderRowNumber = [int]$beginRowAddress + 2 #header row starts 1 row after the class name 
$startDataRowNumber = $startHeaderRowNumber + 1 #student data row starts 1 rows after header row
$beginColumnAddress = $beginAddress.Substring(0,1)
$startColumnHeaderNumber = [BYTE][CHAR]$beginColumnAddress - 65 + 1 #ASCII number of column

#Extract Header Columns Name
$Headers = @{}
$numberOfColumns = 0
$foundHeaderValue = $true
while ($foundHeaderValue -eq $true) {
    $headerCellValue = $sheet.Cells.Item($startHeaderRowNumber, $numberOfColumns+$startColumnHeaderNumber).Text 
    if ($headerCellValue.Trim().Length -eq 0) {
        $foundHeaderValue = $false
    } else {
        $numberOfColumns++
        if($Headers.ContainsValue($headerCellValue))
        {
            #do not add any duplicate column again.
        }
        else
        {            
            $Headers.$numberOfColumns = $headerCellValue
        }
    }
}

#Extract Student Information Rows
$results = @()
$rowNumber = $startDataRowNumber
$finish = $false
while($finish -eq $false)
{
    if ($rowNumber -gt 1) {
        $result = @{}        
        foreach ($columnNumber in $Headers.GetEnumerator()) {
            $columnName = $columnNumber.Value
            $cellValue = $sheet.Cells.Item($rowNumber, $columnNumber.Name+($startColumnHeaderNumber-1)).Value2 # student data row, student data column number
            if($cellValue -eq $null)
            {
                $finish = $true
                break;
            }
            $result.Add($columnName.Trim(),$cellValue.Trim())
        }
        if($finish -eq $false)
        {
            $result.Add("RowNumber",$rowNumber) #adding excel sheet row number for validation        
            $results += $result
            $rowNumber++
        }
    }
}

#input excel and output json file name
$inputFileName = Split-Path $InputFileFullPath -leaf
$jsonOutputFileName = "$($inputFileName.Split(".")[0])-$SubjectName-$ClassName.json"
$jsonOutputFileFullPath = [System.IO.Path]::GetFullPath($jsonOutputFileName)

#create json file and close excel file
Write-Host "Converting sheet '$SubjectName' to '$jsonOutputFileFullPath'"
$ignoreOutput = $results | ConvertTo-Json | Out-File -Encoding ASCII -FilePath $jsonOutputFileFullPath
$ignoreOutput = $excelApplication.Workbooks.Close()
$ignoreOutput = [void][System.Runtime.InteropServices.Marshal]::ReleaseComObject($excelApplication) 
The output JSON file will look like below
[
    {
        "Room Type":  "Standard",
        "RowNumber":  46,
        "Student Name":  "Alex",
        "Student#":  "RL45",
        "LAN Port #":  "LAN Port 7-8",
        "Logical Seat Location":  "SL 11",
        "Actual Seat Location":  "Seat43",
        "Monitor Cable Port":  "C-D"
    },
    {
        "Room Type":  "Standard",
        "RowNumber":  47,
        "Student Name":  "Alex",
        "Student#":  "RL45",
        "LAN Port #":  "LAN Port 5-6",
        "Logical Seat Location":  "SL 11",
        "Actual Seat Location":  "Seat43",
        "Monitor Cable Port":  "A-B"
    },
    {
        "Room Type":  "Standard",
        "RowNumber":  48,
        "Student Name":  "John",
        "Student#":  "RL47",
        "LAN Port #":  "LAN Port 3-4",
        "Logical Seat Location":  "SL 11",
        "Actual Seat Location":  "Seat43",
        "Monitor Cable Port":  "C-D"
    },
    {
        "Room Type":  "Standard",
        "RowNumber":  49,
        "Student Name":  "John",
        "Student#":  "RL47",
        "LAN Port #":  "LAN Port 1-2",
        "Logical Seat Location":  "SL 11",
        "Actual Seat Location":  "Seat43",
        "Monitor Cable Port":  "A-B"
    },
    {
        "Room Type":  "Standard",
        "RowNumber":  50,
        "Student Name":  "Victor",
        "Student#":  "RL35",
        "LAN Port #":  "LAN Port 7-8",
        "Logical Seat Location":  "SL 10",
        "Actual Seat Location":  "Seat33",
        "Monitor Cable Port":  "C-D"
    },
    {
        "Room Type":  "Standard",
        "RowNumber":  51,
        "Student Name":  "Victor",
        "Student#":  "RL35",
        "LAN Port #":  "LAN Port 5-6",
        "Logical Seat Location":  "SL 10",
        "Actual Seat Location":  "Seat33",
        "Monitor Cable Port":  "A-B"
    },
    {
        "Room Type":  "Standard",
        "RowNumber":  52,
        "Student Name":  "Honey",
        "Student#":  "RL42",
        "LAN Port #":  "LAN Port 3-4",
        "Logical Seat Location":  "SL 10",
        "Actual Seat Location":  "Seat33",
        "Monitor Cable Port":  "C-D"
    }
]

Feel free to drop your feedback and inputs on this page. Till then, Happy Scripting!!!

Using variables in multiline Verbatim String in C#

Hi All,

I had a requirement to pass a json payload to HttpRequest. Json payload was expected to be dynamic in nature, so that it can be utilized for creating multiple HTTP requests.

It took me some time to figure out the answer so here I am writing this blog to help others like me.

Sample Json payload given below. Requirement was to pass variable to ServerName and to some other fields in the payload (I have not mentioned them all here to keep this example simple and neat)

string createTicketJson =
@"[
    {
        ""op"": ""Add"",
        ""Path"": ""/fields/System.Title"",
        ""Value"": ""Server 1234: Shutdown Request""
    },
    {
        ""op"": ""Add"",
        ""Path"": ""/fields/System.Description"",
        ""Value"": ""Please shutdown Server 1234. Ticket can be closed after completion of request.""
    },
    {
        ""op"": ""Add"",
        ""Path"": ""/fields/System.Severity"",
        ""Value"": ""3""
    },
    {
        ""op"": ""Add"",
        ""Path"": ""/fields/System.Requester"",
        ""Value"": ""Sonam""
    },
    {
        ""op"": ""Add"",
        ""Path"": ""/fields/System.Notifications"",
        ""Value"": ""sonam@xyz.com""
    }
]";

A static Json payload will look like below. I have shown the payload in a MessageBox for readability purpose.

Solution

With C# 6, string interpolation can be used. So I added a $ sign in front of createTicketJson variable and replaced hardcoded value of Server Name ‘1234’ with variable serverName in curly brackets {serverName}.

This gave me a compilation error and I realized that my single curly bracket { is giving this error since it expects a single line value (variable) inside it.

To resolve this issue and treat curly bracket as text (instead of variable holder), it needs to be duplicated like below and TADA you have the dynamic version ready for json payload.

Final payload will look like below

string createTicketJson =
$@"[
    {{
        ""op"": ""Add"",
        ""Path"": ""/fields/System.Title"",
        ""Value"": ""Server {serverName}: Shutdown Request""
    }},
    {{
        ""op"": ""Add"",
        ""Path"": ""/fields/System.Description"",
        ""Value"": ""Please shutdown Server {serverName}. Ticket can be closed after completion of request.""
    }},
    {{
        ""op"": ""Add"",
        ""Path"": ""/fields/System.Severity"",
        ""Value"": ""3""
    }},
    {{
        ""op"": ""Add"",
        ""Path"": ""/fields/System.Requester"",
        ""Value"": ""Sonam""
    }},
    {{
        ""op"": ""Add"",
        ""Path"": ""/fields/System.Notifications"",
        ""Value"": ""sonam@xyz.com""
    }}
]";

Hope this was helpful. Happy Coding!!!

Friday 28 September 2018

Tableau Dashboard – No records Found!


There are multiple blogs available on internet who talks about the same topic – how to show ‘No Records Found’ message on a tableau sheet. BUT none of them actually helped me to implement this task.
So when I succeeded, I thought to pen down this blog to help several others who may struggle to find out this information like I did.

Here goes my blog with step by step process with screenshots


1. I have created a tableau sheet ‘applications’ which has Environment, Host ID and Count of Applications Installed as fields. There is a filter added on ‘Date’ field. Refer screenshot below.

2. As per our requirement, if records exists in database for given relative date, data should appear.


3.       If records does not exist in database for selected relative date, ‘No Records Found’ message should appear.


4.       For this functionality, a dashboard is required since this can not be achieved using single tableau sheet. Create an empty dashboard by clicking on ‘+’ sign at the bottom bar of tableau desktop. I have named the dashboard as ‘No Data Found Example’ for better understanding.

5.       On the Dashboard, drag and drop a ‘Horizontal’ container object in ‘Tiled’ mode.

6.       Then drag and drop a ‘Text’ object inside the horizontal container in ‘Floating’ mode. Add text to the object and change font as per requirement.

7.       Relocate/Adjust  text object to the required location in the container.

8.       Drag and drop the Applications sheet on the container in ‘Floating’ mode

9.       Relocate/Adjust ‘Relative Date’ filter on the container to the required location.

1.   Relocate/Adjust ‘Application’ sheet on the container to the required location.

1.   And wohoo, you are all set. Test the dashboard by selecting different ‘Relative Date’ filter.



Hope this blog helped you. Your valuable feedback is welcome.
Till then, Happy Scripting!

Friday 2 June 2017

Load Balancer Template with multiple Health probes and Load Balancing rules

This template allows you to create an internal load balancer with multiple Health probes and Load balancing rules. Same logic can be applied to Inbound NAT rules if you wish to create them as well in Load Balancer.
To read more about Azure Load Balancer, refer this article
Below is a snapshot from JSON Outline window
Load Balancer mainly has below properties
  1. Frontend IP Configuration
  2. Backend Address Pools
  3. Health Probes
  4. Load Balancing Rules
  5. Inbound NAT rules (not covered in this post)
Health probes and Load Balancing rules are created under copy section as we need to create them based on the parameter array. To read more about copy function, read this article.
Below is expanded copy section for Health Probes. Note that the name of the section should be ‘probe’. This template defines below properties of a Health Probe
  1. Protocol
  2. Port
  3. intervalInSeconds (amount of time between probe attempts)
  4. numberOfProbes (Unhealthy Threshold)
  5. requestPath (the uri used for requesting health status from the backend endpoint)
Below is expanded copy section for Load Balancing rules. Note that the name of the section should be ‘loadBalancingRules’. This template defines below properties of a Load Balancing rule
  1. Frontend IP Configuration
  2. Backend Address Pool
  3. Probe (Health Probe)
  4. Protocol
  5. Frontend Port
  6. Backend Port
  7. idleTimeoutInMinutes (keep a TCP or HTTP connection open without relying on clients)
  8. enableFloatingIP (It can be enabled only if port and Backend port matches)
Below is the full template
{
“$schema”: “https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#”,
“contentVersion”: “1.0.0.0”,
“parameters”: {
“loadBalancerName”: {
 “type”: “string”
},
“subscriptionId”: {
“type”: “string”
},
“virtualNetworkName”: {
“type”: “string”
},
“subnetName”: {
“type”: “string”
},
“location”: {
“type”: “string”
},
“lbFrontendIPPoolName”: {
“type”: “string”,
“defaultValue”: “LoadBalancerFrontEnd”
},
“lbBackendPoolName”: {
“type”: “string”,
“defaultValue”: “LoadBalancerBackEnd”
},
“healthProbes”: {
“type”: “array”,
“defaultValue”: [
{
“name”: “HealthProbe-TCP-80”,
“protocol”: “TCP”,
“port”: “80”,
“intervalInSeconds”: “15”,
“numberOfProbes”: “2”,
“requestPath”: null
},
{
“name”: “HealthProbe-TCP-443”,
“protocol”: “TCP”,
“port”: “443”,
“intervalInSeconds”: “15”,
“numberOfProbes”: “2”,
“requestPath”: null
},
{
“name”: “HealthProbe-HTTP-443”,
“protocol”: “HTTP”,
“port”: “443”,
“intervalInSeconds”: “15”,
“numberOfProbes”: “2”,
“requestPath”: “TestPath”
}
]
},
“lbRules”: {
“type”: “array”,
“defaultValue”: [
{
“name”: “HTTP”,
“lbFrontendIPPoolName”: “LoadBalancerFrontEnd”,
“lbBackendPoolName”: “LoadBalancerBackEnd”,
“healthProbe”: “HealthProbe-TCP-80”,
“protocol”: “TCP”,
“frontendPort”: “80”,
“backendPort”: “80”,
“idleTimeoutInMinutes”: “15”,
“enableFloatingIP”: false
},
{
“name”: “HTTPS”,
“lbFrontendIPPoolName”: “LoadBalancerFrontEnd”,
“lbBackendPoolName”: “LoadBalancerBackEnd”,
“healthProbe”: “HealthProbe-TCP-443”,
“protocol”: “TCP”,
“frontendPort”: “443”,
“backendPort”: “443”,
“idleTimeoutInMinutes”: “15”,
“enableFloatingIP”: false
}
]
}
},
“variables”: {
“vnetID”: “[resourceId(‘Microsoft.Network/virtualNetworks’, parameters(‘virtualNetworkName’))]”,
“subnetRef”: “[concat(variables(‘vnetID’),’/subnets/’,variables(‘subnetName’))]”,
“lbID”: “[resourceId(‘Microsoft.Network/loadBalancers’, parameters(‘loadBalancerName’))]”
},
“resources”: [
{
“apiVersion”: “2017-03-01”,
“name”: “[parameters(‘loadBalancerName’)]”,
“type”: “Microsoft.Network/loadBalancers”,
“location”: “[parameters(‘location’)]”,
“properties”: {
“frontendIPConfigurations”: [
{
“name”: “[parameters(‘lbFrontendIPPoolName’)]”,
“properties”: {
“subnet”: {
“id”: “[variables(‘subnetRef’)]”
}
}
}
],
“backendAddressPools”: [
{
“name”: “[parameters(‘lbBackendPoolName’)]”
}
],
“copy”: [
{
“name”: “probes”,
“count”: “[length(parameters(‘healthProbes’))]”,
“input”: {
“name”: “[parameters(‘healthProbes’)[copyIndex(‘probes’)].name]”,
“properties”: {
“protocol”: “[parameters(‘healthProbes’)[copyIndex(‘probes’)].protocol]”,
“port”: “[parameters(‘healthProbes’)[copyIndex(‘probes’)].port]”,
“intervalInSeconds”: “[parameters(‘healthProbes’)[copyIndex(‘probes’)].intervalInSeconds]”,
“numberOfProbes”: “[parameters(‘healthProbes’)[copyIndex(‘probes’)].numberOfProbes]”,
“requestPath”: “[parameters(‘healthProbes’)[copyIndex(‘probes’)].requestPath]”
}
}
},
{
“name”: “loadBalancingRules”,
“count”: “[length(parameters(‘lbRules’))]”,
“input”: {
“name”: “[parameters(‘lbRules’)[copyIndex(‘loadBalancingRules’)].name]”,
“properties”: {
“frontendIPConfiguration”: {
“id”: “[concat(resourceId(‘Microsoft.Network/loadBalancers’, parameters(‘loadBalancerName’)), ‘/frontendIpConfigurations/’,parameters(‘lbRules’)[copyIndex(‘loadBalancingRules’)].lbFrontendIPPoolName)]”
},
“backendAddressPool”: {
“id”: “[concat(resourceId(‘Microsoft.Network/loadBalancers’, parameters(‘loadBalancerName’)), ‘/backendAddressPools/’,parameters(‘lbRules’)[copyIndex(‘loadBalancingRules’)].lbBackendPoolName)]”
},
“probe”: {
“id”: “[concat(resourceId(‘Microsoft.Network/loadBalancers’, parameters(‘loadBalancerName’)), ‘/probes/’,parameters(‘lbRules’)[copyIndex(‘loadBalancingRules’)].healthProbe)]”
},
“protocol”: “[parameters(‘lbRules’)[copyIndex(‘loadBalancingRules’)].protocol]”,
“frontendPort”: “[parameters(‘lbRules’)[copyIndex(‘loadBalancingRules’)].frontendPort]”,
“backendPort”: “[parameters(‘lbRules’)[copyIndex(‘loadBalancingRules’)].backendPort]”,
“idleTimeoutInMinutes”: “[parameters(‘lbRules’)[copyIndex(‘loadBalancingRules’)].idleTimeoutInMinutes]”,
“enableFloatingIP”: “[parameters(‘lbRules’)[copyIndex(‘loadBalancingRules’)].enableFloatingIP]”
}
}
}
]
}
}
],
“outputs”: {
“LB”: {
“type”: “object”,
“value”: “[reference(concat(‘Microsoft.Network/loadBalancers/’, parameters(‘loadBalancerName’)))]”
}
}
}

Hope this was helpful. Happy Coding!