Saturday, September 23, 2017

Generating html pages using XSLT and powershell

Powershell to create HTML files from XSLT template

$xslPath = "C:\Users\ggoudar\Desktop\xslt\template.xslt"
$outputStream = New-Object -TypeName "System.IO.MemoryStream"
$arglist = New-Object -TypeName "System.Xml.Xsl.XsltArgumentList"
$XslTransform  = New-Object -TypeName "System.Xml.Xsl.XslCompiledTransform"
$reader  = New-Object -TypeName "System.IO.StreamReader" -ArgumentList $outputStream
$XslTransform.Load($xslPath)
[xml]$XmlDocument = Get-content "C:\Users\ggoudar\Desktop\xslt\data.xml"
$XslTransform.Transform($XmlDocument,$arglist,$outputStream)
$outputStream.Position = 0L
$transformed =  $reader.ReadToEnd()
$tempFile = "$([System.IO.Path]::GetTempPath())$([Guid]::NewGuid()).html"
$null = Out-File -NoClobber -FilePath $tempFile -InputObject $transformed -Force

XSLT file for generating the summary report

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
  <xsl:output method="html" indent="no"/>
  <xsl:template match="/">
    <html lang="en">
      <head>
        <meta charset="utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <meta name="description" content="" />
        <meta name="author" content="" />
        <meta charset="utf-8" />
        <title>Report</title>
        <style type="text/css">
        </style>
      </head>
      <body>
        <div class="container-fluid">
          <div class="row">
            <div class="col-sm-10 col-sm-offset-1 col-md-10 col-md-offset-1 main">
              <div class="panel panel-primary">
                <div class="panel-heading">
                  Summary - IRM
                </div>
                <div class="panel-body">
                  <xsl:for-each select="Report/Subscription">
                    <table class="table table-striped">
                      <tbody>
                        <tr>
                          <td>
                            <xsl:value-of select="@Name"/>
                            <xsl:apply-templates select="ResourceGroup"/>
                          </td>
                        </tr>
                      </tbody>
                    </table>
                  </xsl:for-each>
                </div>
              </div>
            </div>
          </div>
        </div>
      </body>
    </html>
  </xsl:template>
  <xsl:template match="ResourceGroup">
    <xsl:variable name="nodes" select="node()"/>
    <table class="table table-striped">
      <tbody>
        <tr>
          <td>
            <xsl:for-each select="@Name">
              <xsl:value-of select="." />
              <xsl:call-template name="DisplayResourceDetails">
                <xsl:with-param name="nodes" select = "$nodes" />
              </xsl:call-template>
            </xsl:for-each>
          </td>
        </tr>
      </tbody>
    </table>
  </xsl:template>
  <xsl:template name = "DisplayResourceDetails" >
    <xsl:param name = "nodes" />
    <table class="table table-striped">
      <thead>
        <tr>
          <th>Resource Type</th>
          <th>Non-Compliant Resources</th>
          <th>Errors</th>
        </tr>
      </thead>
      <tbody>
        <xsl:for-each select="$nodes">
          <tr>
            <td>
              <xsl:value-of select="@Name"/>
            </td>
            <td>
              <xsl:value-of select="count(Resource/Policy[ValidationResult=0])"/>
            </td>
            <td>
              <xsl:value-of select="count(Resource/Policy[ValidationResult=2])"/>
            </td>
          </tr>
        </xsl:for-each>
      </tbody>
    </table>
  </xsl:template>
</xsl:stylesheet>


XSLT file for generating the detailed report


<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="msxsl"
>
  <xsl:output method="html" indent="no"/>

  <xsl:template match="/">
    <html lang="en">
      <head>
        <meta charset="utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <meta name="description" content="" />
        <meta name="author" content="" />
        <meta charset="utf-8" />
        <title>Report</title>
        <style type="text/css">
        </style>
      </head>
      <body>
        <div class="container-fluid">
          <div class="row">
            <div class="col-sm-10 col-sm-offset-1 col-md-10 col-md-offset-1 main">
              <div class="panel panel-primary">
                <div class="panel-heading">
                  Report Information
                </div>
                <div class="panel-body">
                  <table class="table table-striped">
                    <tbody>
                      <tr>
                        <th>Date :</th>
                        <td>
                          <xsl:value-of select="/Report/Subscription/@Date" />
                        </td>
                      </tr>
                      <tr>
                        <th>Subscription :</th>
                        <td>
                          <xsl:value-of select="/Report/Subscription/@Name" />
                        </td>
                      </tr>
                      <tr>
                        <th>Resource Group :</th>
                        <td>
                          <xsl:value-of select="/Report/Subscription/ResourceGroup/@Name" />
                        </td>
                      </tr>
                    </tbody>
                  </table>
                </div>
              </div>
            </div>
          </div>
          <div class="row">
            <div class="col-sm-10 col-sm-offset-1 col-md-10 col-md-offset-1 main">
              <div class="panel panel-primary">
                <div class="panel-heading">
                  Summary
                </div>
                <table class="table table-striped">
                  <thead>
                    <tr>
                      <th>Resource</th>
                      <th>Resource Type</th>
                      <th>Non-Compliant Rules</th>
                      <th>Errors</th>
                    </tr>
                  </thead>
                  <tbody>
                    <xsl:for-each select="Report/Subscription/ResourceGroup/ResourceType">
                      <xsl:call-template name="DisplayResourceTyperHeader">
                        <xsl:with-param name="nodes" select = "Resource" />
                        <xsl:with-param name="resourceName" select = "@Name" />
                      </xsl:call-template>
                    </xsl:for-each>
                  </tbody>
                </table>
              </div>
            </div>
          </div>
          <xsl:for-each select="Report/Subscription/ResourceGroup/ResourceType">
            <xsl:call-template name="DisplayResourceTypeDetails">
              <xsl:with-param name="nodes" select = "Resource" />
              <xsl:with-param name="resourceName" select = "@Name" />
            </xsl:call-template>
          </xsl:for-each>
        </div>
      </body>
    </html>
  </xsl:template>
  <xsl:template name = "DisplayResourceTyperHeader" >
    <xsl:param name = "nodes" />
    <xsl:param name = "resourceName" />
    <xsl:for-each select="$nodes">
      <tr>
        <td>
          <xsl:value-of select="@Name" />
        </td>
        <td>
          <xsl:value-of select="$resourceName" />
        </td>
        <td>
          <xsl:value-of  select="count(Policy[ValidationResult=0])"/>
        </td>
        <td>
          <xsl:value-of  select="count(Policy[ValidationResult=2])"/>
        </td>
      </tr>
    </xsl:for-each>
  </xsl:template>
  <xsl:template name = "DisplayResourceTypeDetails" >
    <xsl:param name = "nodes" />
    <xsl:param name = "resourceName" />
    <xsl:for-each select="$nodes">
      <div class="row" id="{generate-id(@Name)}">
        <div class="col-sm-10 col-sm-offset-1 col-md-10 col-md-offset-1 main">
          <div class="panel panel-primary">
            <div class="panel-heading">
              <b>
                <xsl:value-of select="@Name" />
              </b>
            </div>
            <div class="panel-body">
              <div class="table-responsive">
                <table class="table table-striped">
                  <thead>
                    <tr>
                      <th>Policy</th>
                      <th>Severity</th>
                      <th>Recommendation</th>
                      <th>Message</th>
                    </tr>
                  </thead>
                  <tbody>
                    <xsl:for-each select="Policy">
                      <tr>
                        <td>
                          <xsl:value-of select="@Name" />
                        </td>
                        <td>
                          <xsl:value-of select="Severity" />
                        </td>
                        <td>
                          <xsl:value-of select="Recommendation" />
                        </td>
                        <td>
                          <xsl:value-of select="Message" />
                        </td>
                      </tr>
                    </xsl:for-each>
                  </tbody>
                </table>
              </div>
            </div>
          </div>
        </div>
      </div>
    </xsl:for-each>
  </xsl:template>
</xsl:stylesheet>


XML file 


<?xml version="1.0" encoding="utf-8"?>
<Report>
  <Subscription Name="Subscription1" Date="19-09-2017 14:31">
    <ResourceGroup Name="ResourceGroup1">
      <ResourceType Name = "Microsoft.Web/sites">
<Resource Name="TestResource">
 <Policy Name="testing">
<Message>Message1</Message>
<Recommendation>It is recommended to choose 64-bit platform to handle more load</Recommendation>
<Severity>Medium</Severity>
<Source>Framework</Source>
<ValidationResult>0</ValidationResult>
 </Policy>
 <Policy Name="testing">
<Message>Message2</Message>
<Recommendation>It is recommended to choose 64-bit platform to handle more load</Recommendation>
<Severity>Medium</Severity>
<Source>Framework</Source>
<ValidationResult>0</ValidationResult>
 </Policy>
            </Resource>
<Resource Name="TestResource9">
 <Policy Name="testing123">
<Message>Message3 </Message>
<Recommendation>It is recommended to choose 64-bit platform to handle more load</Recommendation>
<Severity>Medium</Severity>
<Source>Framework</Source>
<ValidationResult>0</ValidationResult>
<ValidationResultText>Not Compliant</ValidationResultText>               
 </Policy>
            </Resource>
      </ResourceType>
      <ResourceType Name = "Microsoft.ServiceFabric/Cluster">
<Resource Name="TestResource1">
 <Policy Name="testing123456">
<Message>Message4</Message>
<Recommendation>It is recommended to choose 64-bit platform to handle more load</Recommendation>
<Severity>Medium</Severity>
<Source>Framework</Source>
<ValidationResult>2</ValidationResult>
<ValidationResultText>Not Compliant</ValidationResultText>               
 </Policy>
            </Resource>
      </ResourceType>
    </ResourceGroup>
    <ResourceGroup Name="ResourceGroup2">
      <ResourceType Name = "Microsoft.Web/sites">
<Resource Name="TestResource2">
 <Policy Name="testing12390">
<Message>Expected: 'False'. Received: </Message>
<Recommendation>It is recommended to choose 64-bit platform to handle more load</Recommendation>
<Severity>Medium</Severity>
<Source>Framework</Source>
<ValidationResult>2</ValidationResult>
<ValidationResultText>Not Compliant</ValidationResultText>               
 </Policy>
            </Resource>
      </ResourceType>
      <ResourceType Name = "Microsoft.ServiceFabric/Cluster">
<Resource Name="TestResource3">
 <Policy Name="testing12312">
<Message>Expected: 'False'. Received: </Message>
<Recommendation>It is recommended to choose 64-bit platform to handle more load</Recommendation>
<Severity>Medium</Severity>
<Source>Framework</Source>
<ValidationResult>2</ValidationResult>
<ValidationResultText>Not Compliant</ValidationResultText>               
 </Policy>
            </Resource>
      </ResourceType>
    </ResourceGroup>
  </Subscription>
  <Subscription Name="Subscription2">
    <ResourceGroup Name = "ResourceGroup3">
      <ResourceType Name = "Microsoft.Web/sites">
<Resource Name="TestResource4">
 <Policy Name="testing123">
<Message>Expected: 'False'. Received: </Message>
<Recommendation>It is recommended to choose 64-bit platform to handle more load</Recommendation>
<Severity>Medium</Severity>
<Source>Framework</Source>
<ValidationResult>0</ValidationResult>
<ValidationResultText>Not Compliant</ValidationResultText>               
 </Policy>
            </Resource>
      </ResourceType>
      <ResourceType Name = "Microsoft.ServiceFabric/Cluster">
<Resource Name="TestResource5">
 <Policy Name="testing123">
<Message>Expected: 'False'. Received: </Message>
<Recommendation>It is recommended to choose 64-bit platform to handle more load</Recommendation>
<Severity>Medium</Severity>
<Source>Framework</Source>
<ValidationResult>2</ValidationResult>
<ValidationResultText>Not Compliant</ValidationResultText>               
 </Policy>
            </Resource>
      </ResourceType>
    </ResourceGroup>
    <ResourceGroup Name = "ResourceGroup4">
      <ResourceType Name = "Microsoft.Web/sites">
<Resource Name="TestResource6">
 <Policy Name="testing123">
<Message>Expected: 'False'. Received: </Message>
<Recommendation>It is recommended to choose 64-bit platform to handle more load</Recommendation>
<Severity>Medium</Severity>
<Source>Framework</Source>
<ValidationResult>2</ValidationResult>
<ValidationResultText>Not Compliant</ValidationResultText>               
 </Policy>
            </Resource>
      </ResourceType>
      <ResourceType Name = "Microsoft.ServiceFabric/Cluster">
<Resource Name="TestResource7">
 <Policy Name="testing123">
<Message>Expected: 'False'. Received: </Message>
<Recommendation>It is recommended to choose 64-bit platform to handle more load</Recommendation>
<Severity>Medium</Severity>
<Source>Framework</Source>
<ValidationResult>0</ValidationResult>
<ValidationResultText>Not Compliant</ValidationResultText>               
 </Policy>
            </Resource>
      </ResourceType>
    </ResourceGroup>
  </Subscription>
</Report>






Thursday, September 21, 2017

Rest API call to TFS to get the changeset details from the build


Getting the changeset details from VSTS

Enable the setting "Allow script to access OAuth token" in the VSTS team system and run the following powershell commands


$buildId = $env:BUILD_BUILDID

$headers = @{Authorization=("Bearer {0}" -f $env:SYSTEM_ACCESSTOKEN)}

$buildInfoUri = "$($env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI)$env:SYSTEM_TEAMPROJECTID/_apis/build/builds/$($buildId)?api-version=2.0"

$buildInfo = Invoke-RestMethod -Method Get -Uri $buildInfoUri -Headers $headers 

$sourceVersion = $buildInfo.sourceVersion

$changesetUrl = "$($env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI)/_apis/tfvc/changesets/$($sourceVersion)/changes?api-version=2.0"

$changeset = Invoke-RestMethod -Method Get -Uri $changesetUrl -Headers $headers 

Sunday, September 17, 2017

How to trigger a azure web job from a web hook using powershell



$xmlProfile = [xml](Get-AzureRMWebAppPublishingProfile -ResourceGroupName "delete" -Name"testwebgirish" -OutputFile test.xml)
$userName = $xmlProfile.publishData.publishProfile[0].userName.Tostring()
$userPWD = $xmlProfile.publishData.publishProfile[0].userPWD.Tostring()
$url = $webJobs.url
$index = $url.IndexOf('triggeredwebjobs')
$webJobUrl = $url.Substring(0,$index+ "triggeredwebjobs/"
$webHookUrl = $webJobUrl + $webJobs.name + "/run"
$request = [System.Net.WebRequest]::Create($webHookUrl)
#$pair = "$userName"+":"+$userPWD+"
$auth =[System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes($userName+":"+$userPWD))
$request.Method = "POST"
$request.ContentLength = 0;
$request.Headers["Authorization"] = "Basic " + $auth
$response = $request.GetResponse()
$responsestream = $response.GetResponseStream();
[System.IO.StreamReader] $streamReader = New-Object System.IO.StreamReader -argumentList$responsestream;
[string] $results = $streamReader.ReadToEnd();

Saturday, September 9, 2017

New features of TFS 2017

1) Code search

2) Pull request for git

3) Support for package management

4) New build editor

5) Pull based deployment without having to have a separate agent
    The agents are deployed to the target server. We can deploy to all the server or few of teh other ar create a custom one

6) Pipeline as code 

Azure service fabric


Azure service fabric application contains
Application manifest : It contains the application metadata and the details about one or more services
Service manifest  : It contains details about the code, data and config
Settings.xml  : To provide the configuration values for the services

Service can be stateless or state full services. State full service can be further partitioned which can have further replica

Partition is done when there is huge amount of data to be highly sclalable

We can easily increase the instance of the service by specifying the instance count

Deploy azure service application
  • Create a package in VS
  • Upload the package to image store
  • Create a template or the application type 
  • Create the application or instance
  • Create the service instance 
Upgrade the application
  • Change the version of the manifest files
  • Update the package to image store
  • Run the application upgrade command 

Powershell to deploy the azure service fabric application

Connect-serviceFabricCluster -ConnectionEndpoint serverfabriccluster.southindia.cloudapp.azure.com:19000

Import-Module "$ENV:ProgramFiles\Microsoft SDKs\Service Fabric\Tools\PSModule\ServiceFabricSDK\ServiceFabricSDK.psm1"

$path = "c:\users\girish\documents\visual studio 2015\Projects\stateful\stateful\pkg\Debug"

Copy-ServiceFabricApplicationPackage -ApplicationPackagePath $path -ApplicationPackagePathInImageStore MyApplicationV1 -ImageStoreConnectionString (Get-ImageStoreConnectionStringFromClusterManifest(Get-ServiceFabricClusterManifest)) -TimeoutSec 1800

Register-ServiceFabricApplicationType MyApplicationV1

Get-ServiceFabricApplicationType

New-ServiceFabricApplication fabric:/MyApp statefulType 1.0.0


Powershell to remove  the azure service fabric application 

Remove-ServiceFabricApplication fabric:/MyApp
Remove-ServiceFabricApplicationType statefulType 1.0.0


NodeTypes

Service Fabric is made up of Nodetypes which can be defined has a front end and back end and each node type will have its own subnet and each subnet can have it own NSG rules

Types of Application 

one classic application which will run as a guest executables
and the other microservice application which will use the service fabric programming model 

Durability: Azure service fabric uses VMSS which provides auto scaling but this does not mean we can get the scale required very faster. so we have durability which helps in provisioning the scale faster : To use the durabilty of silver, you can create it by ARM templates, By default broze and gold are available in the default azure template

Reliability is based on the number of replicas.To create the reliability tier of silver ,bronze, gold and platnium , we need to use the ARM templates









Sunday, September 3, 2017

Enable Auto scaling for Azure web app



  • Create a new azure auto scale rule
$AutoScaleRule = New-AzureRmAutoscaleRule -MetricName "CpuTime" -MetricResourceId "/subscriptions/2a5fec51-17b3-4a42-a350-91950ce02925/resourceGroups/WebappResourceGroup/providers/Microsoft.Web/sites/WebappResource" -Operator GreaterThan -MetricStatistic Average -Threshold 70 -TimeGrain 00:01:00 -ScaleActionCooldown 00:05:00 -ScaleActionDirection Increase -ScaleActionScaleType ChangeCount -ScaleActionValue "1"

  • Create a new azure auto scale profile

$AutoScaleProfile = New-AzureRmAutoscaleProfile -DefaultCapacity 1 -MaximumCapacity 10 -MinimumCapacity 1 -StartTimeWindow 2017-07-26T00:00:00 -EndTimeWindow 2017-07-27T23:59:00 -TimeWindowTimeZone UTC -Rules $AutoScaleRule -Name "Scale when CPU is HIGH";

  • Add or Enbale autoscale for a azure resource

Add-AzureRmAutoscaleSetting -Location "South Central US" -Name "Auto Scale Setting" -ResourceGroup "/subscriptions/2a5fec51-17b3-4a42-a350-91950ce02925/resourceGroups/testwebappgirish/providers/Microsoft.Web/serverfarms/ServicePlanca0aee64-aed3"  -AutoscaleProfiles $AutoScaleProfile

Enable Diagnostics for a Azure resource and push the info to OMS

Go to the OMS portal and link the Azure subscription.

Get the Workspace Id of the OMS using powershell as show below 

·         (Get-AzureRmOperationalInsightsWorkspace).ResourceId

Get the Resource Id for a Azure resource

·         Get-AzureRmResource -ResourceGroupName webappenv -ResourceName webappenv

Push the Diagnostics information to OMS

·         Set-AzureRmDiagnosticSetting -ResourceId "/subscriptions/2a5fec51-17b3-4a42-a350-91950ce02925/re
sourceGroups/webappenv/providers/Microsoft.Web/sites/webappenv" -WorkspaceId "/subscriptions/2a5fec51-17b3-4a42-a350-919
50ce02925/resourcegroups/mms-cid/providers/microsoft.operationalinsights/workspaces/omsworkspacegirish" -Enabled $true



Saturday, September 2, 2017

Creating Azure policy using powershell

We can create Azure policy by creating the json policy file and use the powershell scripts to create a policy definition and then assign the policy to the azure resource group or the subscription.

  • Following is the json file content for a policy which will not allow resource to be created other than northeurope and west europe

{
    "$schema""http://schema.management.azure.com/schemas/2015-10-01-preview/policyDefinition.json",
    "if": {
        "not": {
            "field""location",
            "in" : ["northeurope" , "westeurope"]
        }
    },
    "then": {
     "effect""deny" 
    }
}

  • ·         Use the below powershell script to assign the policy.


$policyName = Read-Host "Specify the name of the policy";
$policyDescription = Read-Host "Specify the description of the policy"
$policyFile = Read-Host "Path to json policy file";
$resourceGroup = Read-Host "Specify the resource group";
#Login to the Azure Resource Management Account
Login-AzureRmAccount
#Let the user choose the right subscrition
Write-Host "---------------------------------------------------------------------"
Write-Host "Your current subscriptions: " -ForegroundColor Yellow
Get-AzureRMSubscription
Write-Host "Enter the Subscription ID to deploy to: " -ForegroundColor Green
$sub = Read-Host
Set-AzureRmContext -SubscriptionId $sub
clear
$subId = (Get-AzureRmContext).Subscription.SubscriptionId
$subName = (Get-AzureRmContext).Subscription.SubscriptionName
Write-Host "Policy is applied to the resource group: $resourceGroup in subscription: $subName"
$policy = New-AzureRmPolicyDefinition -Name $policyName -Description $policyDescription -Policy $policyFile;
#Assign the Azure Policy
New-AzureRmPolicyAssignment -Name $policyName -PolicyDefinition $policy -Scope"/subscriptions/$sub/resourceGroups/$resourcegroup"