Link to home
Start Free TrialLog in
Avatar of Genesis Energy C&E
Genesis Energy C&E

asked on

Azure Policy API not supplying me with valid Non-Compliant Resource or Policies with PowerShell

Hopefully, someone can assist. Ideally this is the 2nd time I have worked with Azure APIs - in more of a sysadmin role vs Developer.

Essentially what I want is to export the Non-Compliance Microsoft Azure Policies to a HTML report, there is no currently way of doing this so worked on my own method.

Connecting to the PolicyAssignments API I have been successfully able to export the: Azure Policy Names, Azure Policy Descriptions however not the Non Compliant resources or policies. Essentially what I am getting back is a '0', which although is really nice! I know it not to be the truth!

Attached to this post is a screenshot of the HTML export I have managed to do, but don't understand why the Resources & Policies are all coming up as '0'.

This is the code I have so far:

$PolicyResults = @()
ForEach ($subid in $subscriptionId)

{

    $Headers = @{
        'authorization' = "Bearer $token"
        'host'          = 'management.azure.com'
        'contentype'    = 'application/json'
    }


    $url = "https://management.azure.com/subscriptions/$subid/providers/Microsoft.Authorization/policyAssignments?api-version=2017-06-01-preview"


    $policies = Invoke-RestMethod  -Uri $url  -Headers $Headers -Method Get

ForEach ($policy in $policies.value) {

    $id = $policy.name
    $resources = "https://management.azure.com/subscriptions/$subid/providers/Microsoft.Authorization/policyDefinitions/$id/providers/Microsoft.PolicyInsights/policyStates/latest/summarize?api-version=2017-12-12-preview&filter=IsCompliant eq false"


    $a = Invoke-RestMethod  -Uri $resources  -Headers $Headers -Method Post

    ForEach ($value in $a.value)
    {
        $PolicyResults += [pscustomobject]@{
            'Policy Name' = ($policy.properties.displayName)
            'Policy Description' = ($policy.properties.description)
            'Non Compliant Resources'  = ($value.Results.NonCompliantResources)
            'Non Compliant Policies' = ($value.Results.NonCompliantPolicies)
        }
    }


}
}

Open in new window


I am hoping someone can try and replicate my issues and help point me in the right direction. I believe the problem is with the $resources variable but uncertain, have also tried removing the filter and no change.
Avatar of Kyle Santos
Kyle Santos
Flag of United States of America image

Hi,

I am here to help you with your open question.  Do you still need help?  I have the ability to alert more experts if you still need help.

If you solved the problem on your own, would you please post the solution here in case others have the same problem?

If you need me to delete this question just say "Delete."

Thank you for using Experts Exchange.

Regards,

Kyle Santos
Customer Relations
Avatar of Genesis Energy C&E
Genesis Energy C&E

ASKER

Thanks, unfortunately still having a bit of problems, so any help would be appreciated.
Hi,

Please attach the screenshot as it has not come through.
Also, can you please confirm this is similar to the version of Policy API described here:
https://docs.microsoft.com/en-us/azure/azure-policy/policy-compliance#portal?

# Login first with Connect-AzureRmAccount if not using Cloud Shell

$azContext = Get-AzureRmContext
$azProfile = [Microsoft.Azure.Commands.Common.Authentication.Abstractions.AzureRmProfileProvider]::Instance.Profile
$profileClient = New-Object -TypeName Microsoft.Azure.Commands.ResourceManager.Common.RMProfileClient -ArgumentList ($azProfile)
$token = $profileClient.AcquireAccessToken($azContext.Subscription.TenantId)
$authHeader = @{
    'Content-Type'='application/json'
    'Authorization'='Bearer ' + $token.AccessToken
}

# Define the REST API to communicate with
# Use double quotes for $restUri as some endpoints take strings passed in single quotes
$restUri = "https://management.azure.com/subscriptions/{subscriptionId}/providers/Microsoft.PolicyInsights/policyStates/latest/summarize?api-version=2018-04-04"

# Invoke the REST API
$response = Invoke-RestMethod -Uri $restUri -Method POST -Headers $authHeader

# View the response object (as JSON)
$response

Open in new window


If yes, can you tweak it and see if it still works for you. especially api-version=2018-04-04 part along with the necessary filters that you need. If it works then I will be able to provide you the formate you are looking for.

Regards,
Chinmay.
Genesis-EnergyCE,

An expert has replied.

Is there anything else we may assist you with?

Regards,

Kyle Santos
Customer Relations
Thanks, Chinmay. Yes that looks right - will give it a try tonight. Don't have the code with me at work currently and let you know how I get on. Thanks for the assistance.
Hey, Chinmay

Switched to the 2018 API but same issue.

I am able to connect, and get the Policy Name and Description, but the compliance data doesn't seem to be working.

Current script:

$result = Invoke-RestMethod -Uri https://login.microsoftonline.com/$TENANTID/oauth2/token?api-version=1.0 -Method Post -Body @{
  'grant_type'  = 'client_credentials'
  'resource'    = 'https://management.core.windows.net/'
  'client_id'   = "$APPID"
  'client_secret' = "$PASSWORD"
}
$token = $result.access_token

#Sets CSS
$Css = '<style>table{margin:auto; width:98%}
  body{background-color:#fffffF    ; text-align:Center; font-family: Calibri ;}
  p,h2{text-align:Center; font-family: Calibri ;}
  h1 {text-align:Center; font-family: Circular Pro Black; font-weight: bold; color:#464958
  ;  }
  th{background-color:#464958; color:white;}
td{background-color:lightgrey; color:#464958  ; Text-align:Center;} </style>'

##set subscriptionId

$subscriptionId= @('0000000000000000000000', '0000000000000000000000', '0000000000000000000')


$PolicyResults = @()
ForEach ($subid in $subscriptionId)

{

    $Headers = @{
        'authorization' = "Bearer $token"
        'host'          = 'management.azure.com'
        'contentype'    = 'application/json'
    }


    $url = "https://management.azure.com/subscriptions/$subid/providers/Microsoft.Authorization/policyAssignments?api-version=2017-06-01-preview"


    $policies = Invoke-RestMethod  -Uri $url  -Headers $Headers -Method Get

ForEach ($policy in $policies.value) {

    $id = $policy.name
    $resources = "https://management.azure.com/subscriptions/$subid/providers/Microsoft.Authorization/policyDefinitions/$id/providers/Microsoft.PolicyInsights/policyStates/latest/summarize?api-version=2018-04-04"


    $a = Invoke-RestMethod  -Uri $resources  -Headers $Headers -Method Post

    ForEach ($value in $a.value)
    {
        $PolicyResults += [pscustomobject]@{
            'Policy Name' = ($policy.properties.displayName)
            'Policy Description' = ($policy.properties.description)
            'Non Compliant Resources'  = ($value.Results.NonCompliantResources)
            'Non Compliant Policies' = ($value.Results.NonCompliantPolicies)
        }
    }


}
}

$PolicyResults  | ConvertTo-HTML -head "$css <H1> Microsoft Azure Policy Report</H1>" -Title 'Microsoft Azure Policy Report'  | Out-File -FilePath C:\temp\AzurePolicy.html

Open in new window


Example of output:

User generated image
Hi,

I would like to check Output of
$a = Invoke-RestMethod  -Uri $resources  -Headers $Headers -Method Post

Open in new window


Have you tried dumping $a as it is or by debugging the script? If you can please save $a as a plain text and check if we are getting the results from the query or not.

Regards,
Chinmay.
The variable is a large object, compartmentalized. Its all '0' in the object, however there is definitely non-compliant resources in the Azure portal.
I noticed that in the query results variable the results have:

 /providers/Microsoft.Authorization/policyDefinitions/SecurityCenterBuiltIn/providers/Microsoft.PolicyInsights/policyStates/latest/queryResults?api-version=2018-04-04&$from=2018-08-12 09:33:09Z&$to=2018-08-13 09:33:09Z&$filter=IsCompliant eq false; nonCompliantResources=0; nonCompliantPolicies=0}

Not sure if this has altered the results.
Hi,

I would like to see the definition of your policy. Any one policy - sanitize your screen shot and post it here please.
Also the list of policies from the Azure portal which are being reported as compliance violation, post a screenshot of that as well.

https://portal.azure.com/#blade/Microsoft_Azure_Policy/PolicyMenuBlade/Compliance
Genesis-EnergyCE,

An expert has replied.

Is there anything else we may assist you with?

Regards,

Kyle Santos
Customer Relations
Thanks guys. Just closing this question, cheers for the help!
Hi,

Here are steps on how to close your question.
http://support.experts-exchange.com/customer/portal/articles/2527982-how-do-i-close-my-question-

Or just let me know whose answer was the best and which were helpful.
This question needs an answer!
Become an EE member today
7 DAY FREE TRIAL
Members can start a 7-Day Free trial then enjoy unlimited access to the platform.
View membership options
or
Learn why we charge membership fees
We get it - no one likes a content blocker. Take one extra minute and find out why we block content.