Azure-docs: What is the Correct Use of Set-AzJitNetworkAccessPolicy to Set Policy for Multiple VMs?

Created on 1 Aug 2019  Â·  7Comments  Â·  Source: MicrosoftDocs/azure-docs

Following these steps to set JIT VM access via PowerShell has the expected result for VMNAME:

$JitPolicy = (@{ id="/subscriptions/SUBSCRIPTIONID/resourceGroups/RESOURCEGROUP/providers/Microsoft.Compute/virtualMachines/VMNAME"
ports=(@{
     number=22;
     protocol="*";
     allowedSourceAddressPrefix=@("*");
     maxRequestAccessDuration="PT3H"},
     @{
     number=3389;
     protocol="*";
     allowedSourceAddressPrefix=@("*");
     maxRequestAccessDuration="PT3H"})})
$JitPolicyArr=@($JitPolicy)
Set-AzJitNetworkAccessPolicy -Kind "Basic" -Location "LOCATION" -Name "default" -ResourceGroupName "RESOURCEGROUP" -VirtualMachine $JitPolicyArr

Calling Get-AzJitNetworkAccessPolicy returns

Id                : /subscriptions/SUBSCRIPTIONID/resourceGroups/RESOURCEGROUP/providers/Microsoft.Security/locations/[location]/jitNetworkAccessPolicies/VMNAME
Name              : default
Kind              : Basic
VirtualMachines   : {/subscriptions/SUBSCRIPTIONID/resourceGroups/RESOURCEGROUP/providers/Microsoft.Compute/virtualMachines/VMNAME}
Requests          : {}
ProvisioningState : Succeeded

However, following the same steps a second time for VMNAMEB overwrites the first policy for VMNAME:

$JitPolicy = (@{ id="/subscriptions/SUBSCRIPTIONID/resourceGroups/RESOURCEGROUP/providers/Microsoft.Compute/virtualMachines/VMNAMEB"
ports=(@{
     number=22;
     protocol="*";
     allowedSourceAddressPrefix=@("*");
     maxRequestAccessDuration="PT3H"},
     @{
     number=3389;
     protocol="*";
     allowedSourceAddressPrefix=@("*");
     maxRequestAccessDuration="PT3H"})})
$JitPolicyArr=@($JitPolicy)
Set-AzJitNetworkAccessPolicy -Kind "Basic" -Location "LOCATION" -Name "default" -ResourceGroupName "RESOURCEGROUP" -VirtualMachine $JitPolicyArr

Calling Get-AzJitNetworkAccessPolicy returns:

Id                : /subscriptions/SUBSCRIPTIONID/resourceGroups/RESOURCEGROUP/providers/Microsoft.Security/locations/[location]/jitNetworkAccessPolicies/VMNAMEB
Name              : default
Kind              : Basic
VirtualMachines   : {/subscriptions/SUBSCRIPTIONID/resourceGroups/RESOURCEGROUP/providers/Microsoft.Compute/virtualMachines/VMNAMEB}
Requests          : {}
ProvisioningState : Succeeded

Even worse, it leaves the NSG rule for VMNAME even though the policy is gone.

What PowerShell will result in setting the JIT policies for both VMs?


Document Details

⚠ Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.

Pri1 cxp product-question security-centesvc triaged

All 7 comments

@mjcarrabine Thanks for your feedback! We will investigate and update as appropriate.

Update 21 August 2019: The method described below does not have the same effect as enabling JIT access through Azure Security Center. Changing the -Name parameter to anything other than default results in:

  • The VM is listed in Azure Security Center --> Just in time VM Access
  • You can successfully request access from Azure Security Center --> Just in time VM Access
  • However, if you go to the Virtual Machine --> Connect, it is not aware there is a JIT Policy

It looks as if setting the -Name parameter sets the JIT policies for both VMs, but it doesn't appear to be documented anywhere if this is compatible with how Azure Security Center behaves.

Following the steps and setting -Name VMNAME appears to work:

$JitPolicy = (@{ id="/subscriptions/SUBSCRIPTIONID/resourceGroups/RESOURCEGROUP/providers/Microsoft.Compute/virtualMachines/VMNAME"
ports=(@{
     number=22;
     protocol="*";
     allowedSourceAddressPrefix=@("*");
     maxRequestAccessDuration="PT3H"},
     @{
     number=3389;
     protocol="*";
     allowedSourceAddressPrefix=@("*");
     maxRequestAccessDuration="PT3H"})})
$JitPolicyArr=@($JitPolicy)
Set-AzJitNetworkAccessPolicy -Kind "Basic" -Location "LOCATION" -Name VMNAME -ResourceGroupName "RESOURCEGROUP" -VirtualMachine $JitPolicyArr

Calling Get-AzJitNetworkAccessPolicy returns

Id                : /subscriptions/SUBSCRIPTIONID/resourceGroups/RESOURCEGROUP/providers/Microsoft.Security/locations/[location]/jitNetworkAccessPolicies/VMNAME
Name              : VMNAME
Kind              : Basic
VirtualMachines   : {/subscriptions/SUBSCRIPTIONID/resourceGroups/RESOURCEGROUP/providers/Microsoft.Compute/virtualMachines/VMNAME}
Requests          : {}
ProvisioningState : Succeeded

Following the same steps a second time for VMNAMEB and setting -Name VMNAMEB also appears to work

$JitPolicy = (@{ id="/subscriptions/SUBSCRIPTIONID/resourceGroups/RESOURCEGROUP/providers/Microsoft.Compute/virtualMachines/VMNAMEB"
ports=(@{
     number=22;
     protocol="*";
     allowedSourceAddressPrefix=@("*");
     maxRequestAccessDuration="PT3H"},
     @{
     number=3389;
     protocol="*";
     allowedSourceAddressPrefix=@("*");
     maxRequestAccessDuration="PT3H"})})
$JitPolicyArr=@($JitPolicy)
Set-AzJitNetworkAccessPolicy -Kind "Basic" -Location "LOCATION" -Name VMNAMEB -ResourceGroupName "RESOURCEGROUP" -VirtualMachine $JitPolicyArr

Calling Get-AzJitNetworkAccessPolicy now returns:

Id                : /subscriptions/SUBSCRIPTIONID/resourceGroups/RESOURCEGROUP/providers/Microsoft.Security/locations/[location]/jitNetworkAccessPolicies/VMNAME
Name              : VMNAME
Kind              : Basic
VirtualMachines   : {/subscriptions/SUBSCRIPTIONID/resourceGroups/RESOURCEGROUP/providers/Microsoft.Compute/virtualMachines/VMNAME}
Requests          : {}
ProvisioningState : Succeeded

Id                : /subscriptions/SUBSCRIPTIONID/resourceGroups/RESOURCEGROUP/providers/Microsoft.Security/locations/[location]/jitNetworkAccessPolicies/VMNAMEB
Name              : VMNAMEB
Kind              : Basic
VirtualMachines   : {/subscriptions/SUBSCRIPTIONID/resourceGroups/RESOURCEGROUP/providers/Microsoft.Compute/virtualMachines/VMNAMEB}
Requests          : {}
ProvisioningState : Succeeded

@mjcarrabine The PR for the fix has been created and it will be merged soon. Thanks again for pointing this out, I am closing the issue based on this update, please let us know if there is something else that we can help you with.

Thank you @SaurabhSharma-MSFT.

Any idea when we can expect to documentation to be updated?

@SaurabhSharma-MSFT The most recent commit to this page does not seem to have addressed my issue.

Separately, I updated my suggestion on 1 August because it does not solve the problem either.

So, my original question still stands: What PowerShell will result in setting the JIT policies for both VMs?

Since my 1 August attempt at a solution didn't work, this is the best I could come up with.

Instead of changing the -Name parameter, this function retrieves the existing policy, removes any existing policies for the VM we are adding a policy for, adds the new policy, and submits the full updated policy to Set-AzJitNetworkAccessPolicy. It would be great if there were a better way.

Given that JIT Network Access seems to be one of Azure's top security recommendations, I am amazed that I can't find anywhere in the documentation to automate enabling JIT Network Access on VMs if you have more than 1 machine per resource group.

Function Set-IRMJITNetworkAccessPolicy {
    Param (
        [String]$ResourceGroupName,
        [String]$Location,
        [String]$Name = "default",

        [Parameter(Position = 0, Mandatory = $True, HelpMessage = 'Specify the VM Name')]
        [String]$VirtualMachineName,

        [Parameter(Position = 1, Mandatory = $True, HelpMessage = 'Specify remote access port, must be a number between 1 and 65535.')]
        [ValidateRange(1, 65535)]
        [Int]$Port,

        [Parameter(Position = 2, HelpMessage = 'Source IP Address Prefix. (IP Address, or CIDR block) Default = Your IP')]
        [String]$AddressPrefix,

        [Parameter(Position = 3, HelpMessage = 'Specify time range in hours, valid range: 1-24 hours')]
        [ValidateRange(1, 24)]
        [Int]$Time
    )

    $VMInfo = Get-AzVM -ResourceGroup $ResourceGroupName -Name $VirtualMachineName

    $NewJitPolicy = (@{
            id    = "$($VMInfo.Id)"
            ports = (@{
                    number                     = $Port;
                    protocol                   = "*";
                    allowedSourceAddressPrefix = @("$AddressPrefix");
                    maxRequestAccessDuration   = "PT$($time)H"
                })   
        })

    Write-Host "Get Existing JIT Policy. You can Ignore the error if not found."
    $ExistingJITPolicy = (Get-AzJitNetworkAccessPolicy -ResourceGroupName $ResourceGroupName -Location $Location -Name $Name).VirtualMachines
    $UpdatedJITPolicy = $ExistingJITPolicy.Where{$_.id -ne "$($VMInfo.Id)"} # Exclude existing policy for $VirtualMachineName
    $UpdatedJITPolicy.Add($NewJitPolicy)

    #! Enable Access to the VM including management Port, and Time Range in Hours
    Write-Host "Enabling Just in Time VM Access Policy for ($VirtualMachineName) on port number $Port for maximum $time hours..."
    Set-AzJitNetworkAccessPolicy -VirtualMachine $UpdatedJITPolicy -ResourceGroupName $ResourceGroupName -Location $Location -Name $Name -Kind "Basic" | Out-Null
}

Just wanted to second the above. I'm looking at jit enablement and falling over these gotchas

Was this page helpful?
0 / 5 - 0 ratings

Related issues

monteledwards picture monteledwards  Â·  3Comments

JamesDLD picture JamesDLD  Â·  3Comments

mrdfuse picture mrdfuse  Â·  3Comments

spottedmahn picture spottedmahn  Â·  3Comments

AronT-TLV picture AronT-TLV  Â·  3Comments