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?
⚠Do not edit this section. It is required for docs.microsoft.com ➟ GitHub issue linking.
@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
-Nameparameter to anything other thandefaultresults 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