Serverless LAPS powered by Microsoft Intune, Azure Functions and Azure Key Vault!

Serverless LAPS powered by Microsoft Intune, Azure Functions and Azure Key Vault!

I’m excited to introduce a Serverless Local Administrator Password Solution (SLAPS šŸ˜‰) for Windows 10 Intune Managed devices, powered byĀ Microsoft Intune PowerShell scripts,Ā Azure Functions andĀ Azure Key Vault.

Building this solution has been quite a challenge, as there were many obstacles to overcome. If you’ve read the article of Oliver Kieselbach: “Deep dive Microsoft Intune Management Extension – PowerShell Scripts“, then you know that all script contents are logged in plain text (including passwords!)Ā to the IntuneManagementExtension.log file. So I had to come up with a solution that would not expose passwords in plain text at any time.

That’s whereĀ Azure Functions come in! I managed to create an HTTP-based API, using theĀ experimental PowerShell language support in a Function App, that contains all of the logics for returning random passwords on demand and simultaneously storing them securely into an Azure Key Vault. Passwords are contained in a variable and never exposed in plain text.

From the Intune PowerShell script, the Azure Function is queried over a TLS 1.2 encrypted connection, using the Invoke-RestMethod cmdlet. The hostname of the initiating device, and the username defined in the PowerShell Script are used to create the Local Administrator, and are also passed with theĀ POSTĀ method to the Azure Function within the request body of the Invoke-RestMethod cmdlet.

When the Azure Function is triggered, it will return a random generated password to the PowerShell script, and also creates or updates a secret in your Azure Key Vault. The name of the secret is based on the hostname of the device. The value will be the randomly generated password, and the username is added as a tag.

Sounds nice, right? But there’s one more challenge… I don’t want to expose the url containing the authorization code to trigger theĀ Azure Function in plain text within the log file. I want to be able to rely on the contents of Key vault. Exposing this information would allow anyone to read the log file and put false information in the Key vault, by executing the same cmdlets with modified data. I figured out I could manipulate the log file during the runtime of the PowerShell script using the code below:

This would remove each line from the log file that matches the “azurewebsites.net” string.

Note:
Please note that this is just a workaround to hide information from the log file. It is absolutely notĀ waterproof. An ‘attacker’ will still be able to retrieve the contents of the PowerShell script. TheĀ Intune Management Extension will download scripts just before they are executed to “C:\Program Files (x86)\Microsoft Intune Management Extension\Policies\Scripts”, where it will be removed after execution.

Your Local Administrator credentials are safe, because they are never exposed, however your Key vault may get manipulated if the Azure Function is abused. If you require a better solution, please vote forĀ Secure authentication within PowerShell scripts for Intune MDM on theĀ Microsoft IntuneĀ UserVoice forums

 


Prerequisites

Before being able to configure the Local Administrator Password Solution using the instructions below, the following prerequisites must be met:

 

Note:
The Azure Function is using the experimental PowerShell language support. I’d be happy to share a C# example if anyone is up for the challenge šŸ™‚

 


Configuration

Considering that a Function App and Key vault have already been deployed, I’ve divided the configuration of the Serverless Local Administrator Password Solution into six parts:

  1. Register a Managed Service Identity with Azure Active Directory;
  2. Grant the Managed Service Identity access to theĀ Key vault;
  3. Create theĀ Azure Function;
  4. Test the Azure Function;
  5. Deploy theĀ PowerShell script withĀ Microsoft Intune;
  6. Validate the deployment of the PowerShell script;

 

1. Register a Managed Service Identity with Azure Active Directory

A Managed Service Identity needs to be registered with Azure Active Directory first, that will be used to authenticate with theĀ Azure Key Vault.

  • Open theĀ Azure Portal;
  • Navigate toĀ Function Apps;
  • In theĀ Functions Apps blade, select the Function App you wish to configure;
  • Navigate to the Platform features tab;
  • UnderĀ Networking, clickĀ Managed service identity;
  • SetĀ Register with Azure Active Directory toĀ On and clickĀ Save.

2. Grant the Managed Service Identity access to the Key vault

The next step is to add the Managed Service Identity to an Access policy in the Key vault.

  • Navigate toĀ Key vaults;
  • On theĀ Key vaults blade, select theĀ Key vault you wish to configure;
  • In theĀ Key vaultĀ blade that displays, clickĀ Access policies;
  • In theĀ Access policies blade that displays, clickĀ Add new;
  • In theĀ Add access policy blade that displays, clickĀ Select principal;
  • Enter the name of yourĀ Function App and clickĀ Select;
  • In theĀ Secret permissions, selectĀ Secret Management OperationsĀ >Ā Set;
  • ClickĀ OK and click Save.

 

3. Create the Azure Function

Now that theĀ Managed Service IdentityĀ of theĀ Function App has been granted access toĀ Set secrets in theĀ Key vault. It’s time to create the Azure Function.

  • Navigate toĀ Function Apps;
  • In theĀ Functions Apps blade, select the Function App you wish to configure;
  • SelectĀ Functions and clickĀ New function;
  • Enable theĀ Experimental Language Support functions;
  • ClickĀ HTTP trigger >Ā PowerShell;
  • Configure theĀ new function:
    • Language: PowerShell
    • Name: Set-KeyVaultSecret
    • Authorization level:Ā Function
  • Replace the content of the Set-KeyVaultSecret function with the PowerShell code of theĀ Set-KeyVaultSecret.ps1 file downloaded from the TechNet Gallery;
  • Set the name of your Key vault in the $keyVaultName variable;
  • ClickĀ Save;

Note:
Take note of the Function URL (</> Get Function URL), which needs to be set in theĀ New-LocalAdmin.ps1 script later.

By default the Function App requires a TLS connection with a minimum version of 1.2.

 

4. Test the Azure Function

Before continuing to configure the PowerShell script in Intune that creates theĀ Local Administrator accounts, it’s recommended to test if the Azure Function works as expected.

  • Grab the request body from theĀ New-LocalAdmin.ps1 script;
  • Replace the variables with values, for example:
  • Run the Azure Function and review the output;
    If theĀ Function runs successfully, a random password is returned theĀ Output pane.
  • Validate the creation of the secret in theĀ Key vault as defined in theĀ keyName.

 

5. Deploy the PowerShell script with Microsoft Intune

  • Modify the configurationĀ section of theĀ New-LocalAdmin.ps1 script;
    • Choose a username for the Local Administrator accounts;
    • Enter the Function URL;

      The New-LocalAdmin.ps1 script will restart itself in a 64-bit process, because cmdlets like New-LocalUser are not available in a 32-bit process, which is the architecture of the Intune Management Extension agent.

  • In the Azure Portal, navigate toĀ Intune >Ā Device ConfigurationĀ >Ā PowerShell scripts;
  • In theĀ PowerShell scriptsĀ blade, clickĀ + Add;
  • On theĀ Add PowerShell script blade, enter the following information and click Create;
    • Name: New-LocalAdmin
    • Script Location:Ā Select theĀ New-LocalAdmin.ps1 file, previously downloaded from the TechNet Gallery
  • In theĀ New-LocalAdminĀ blade that displays, click Assignments;
  • Select a group you wish to deploy the solution to;
  • SaveĀ the assignments;

 

Note:
PowerShell scripts can only be deployed to users. On shared devices, the provided PowerShell script will change the password of the Local Administrator user every time a new user logs on to a device.

 

6. Validate the deployment of the PowerShell script

PowerShell scripts are executed by the Intune Management Extension. The agent will check every 60 minutes if a script is ready to be deployed. You can force a sync by restarting theĀ Microsoft Intune Management Extension Service on the device.

The status of theĀ PowerShell scriptĀ deployment is returned to the Monitor > Device/User status overview in Intune.

When the PowerShell script succeeds, validate the creation of a Local Administrator on the device, and that the credentials were stored in the Key vault.

 


More information

Need to troubleshoot further? Check the log files on a device at C:\ProgramData\Microsoft\IntuneManagementExtension\Logs\IntuneManagementExtension.log, which contains the logging for PowerShell Scripts.

If you have any questions or feedback, feel free to leave a comment!

 

50 thoughts on “Serverless LAPS powered by Microsoft Intune, Azure Functions and Azure Key Vault!

  1. Pretty nice man… thanks for this! Have you made any changes since posting? Any better ways to control access to being able to invoke the Azure function, besides PKI?
    I went ahead and upvoted the uservoice on secure authentication through PowerShell.

    Thanks again!

  2. So I am failing on this somehow, interface changed and the “Managed Service Identity” has changed to “Identity” and the object seems to never exist when I create it. As such, when I run the script, I get this in out Output:

    {
    “id”: “f7a61fa2-6aec-4672-b547-77154614306d”,
    “requestId”: “abeff90e-055f-4519-902d-6cfbcc64f389”,
    “statusCode”: 500,
    “errorCode”: 0,
    “message”: “An error has occurred. For more information, please check the logs for error ID f7a61fa2-6aec-4672-b547-77154614306d”
    }

    and in the log window i receive:

    2019-03-19T16:37:16.952 [Info] Function started (Id=8459ee2d-f154-4355-aa5d-db8d0242faf8)
    2019-03-19T16:37:17.311 [Error] Invoke-RestMethod : {“error”:{“code”:”Forbidden”,”message”:”Access denied”,”innererror”:{“code”:”AccessDenied”}}}
    at run.ps1: line 34
    + Invoke-RestMethod
    + _________________
    + CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
    2019-03-19T16:37:17.342 [Error] Exception while executing function: Functions.Set-KeyVaultSecret. Microsoft.Azure.WebJobs.Script: PowerShell script error. Microsoft.PowerShell.Commands.Utility: The remote server returned an error: (403) Forbidden.
    2019-03-19T16:37:17.373 [Error] Function completed (Failure, Id=8459ee2d-f154-4355-aa5d-db8d0242faf8, Duration=416ms)

    the permissions are set properly per this article so I am unsure why this is occurring.

    1. Hi Corey,

      You are getting an authentication error on setting the secret to Azure Key Vault. It seems that the Managed Service Identity (Service Principal) of the Function App itself does not have the “Secret permissions” set to “Set” on the Azure Key Vault, hence you get a 403 forbidden error.

      Can you double check that the “Access policy” on the Azure Key Vault, that it contains the “Application” (Function App) with “Secret permissions” set to “Set”? When I remove my Access Policy, I get the same error as you do.

  3. Admiring the time and energy you put into your blog and in depth information you provide.
    It’s awesome to come across a blog every once
    in a while that isn’t the same unwanted rehashed material.
    Fantastic read! I’ve saved your site and I’m adding
    your RSS feeds to my Google account.

  4. Hi John, I getting this error. Please let me know where I went wrong?

    2019-04-25T04:39:49 Welcome, you are now connected to log-streaming service.
    2019-04-25T04:40:49 No new trace in the past 1 min(s).
    2019-04-25T04:41:49 No new trace in the past 2 min(s).
    2019-04-25T04:42:27.065 [Information] Executing ‘Functions.Set-KeyVaultSecret’ (Reason=’This function was programmatically called via the host APIs.’, Id=9907eb8d-80af-426c-b3a9-a5ae9eeece66)
    2019-04-25T04:42:27.113 [Error] Executed ‘Functions.Set-KeyVaultSecret’ (Failed, Id=9907eb8d-80af-426c-b3a9-a5ae9eeece66)
    Result: Failure
    Exception: No parameter defined in the script or function for the input binding ‘Request’.

    Stack: at Microsoft.Azure.Functions.PowerShellWorker.AzFunctionInfo..ctor(RpcFunctionMetadata metadata) in C:\projects\azure-functions-powershell-worker\src\FunctionInfo.cs:line 120
    at Microsoft.Azure.Functions.PowerShellWorker.FunctionLoader.LoadFunction(FunctionLoadRequest request) in C:\projects\azure-functions-powershell-worker\src\FunctionLoader.cs:line 45
    at Microsoft.Azure.Functions.PowerShellWorker.RequestProcessor.ProcessFunctionLoadRequest(StreamingMessage request) in C:\projects\azure-functions-powershell-worker\src\RequestProcessor.cs:line 187
    2019-04-25T04:43:49 No new trace in the past 1 min(s).
    2019-04-25T04:44:49 No new trace in the past 2 min(s).
    2019-04-25T04:45:49 No new trace in the past 3 min(s).
    2019-04-25T04:46:44.174 [Information] Executing ‘Functions.Set-KeyVaultSecret’ (Reason=’This function was programmatically called via the host APIs.’, Id=b62dc2e5-9ae0-4315-9a6c-200a7be2a4bc)
    2019-04-25T04:46:44.215 [Error] Executed ‘Functions.Set-KeyVaultSecret’ (Failed, Id=b62dc2e5-9ae0-4315-9a6c-200a7be2a4bc)
    Result: Failure
    Exception: No parameter defined in the script or function for the input binding ‘Request’.

    Stack: at Microsoft.Azure.Functions.PowerShellWorker.AzFunctionInfo..ctor(RpcFunctionMetadata metadata) in C:\projects\azure-functions-powershell-worker\src\FunctionInfo.cs:line 120
    at Microsoft.Azure.Functions.PowerShellWorker.FunctionLoader.LoadFunction(FunctionLoadRequest request) in C:\projects\azure-functions-powershell-worker\src\FunctionLoader.cs:line 45
    at Microsoft.Azure.Functions.PowerShellWorker.RequestProcessor.ProcessFunctionLoadRequest(StreamingMessage request) in C:\projects\azure-functions-powershell-worker\src\RequestProcessor.cs:line 187
    2019-04-25T04:47:49 No new trace in the past 1 min(s).
    2019-04-25T04:48:49 No new trace in the past 2 min(s).
    2019-04-25T04:49:49 No new trace in the past 3 min(s).
    2019-04-25T04:50:49 No new trace in the past 4 min(s).
    2019-04-25T04:51:49 No new trace in the past 5 min(s).
    2019-04-25T04:52:49 No new trace in the past 6 min(s).
    2019-04-25T04:53:49 No new trace in the past 7 min(s).
    2019-04-25T04:54:49 No new trace in the past 8 min(s).
    2019-04-25T04:55:49 No new trace in the past 9 min(s).
    2019-04-25T04:56:49 No new trace in the past 10 min(s).
    2019-04-25T04:57:49 No new trace in the past 11 min(s).
    2019-04-25T04:58:49 No new trace in the past 12 min(s).

    2019-04-25T04:59:34 The application was terminated.

    1. Hi Nkoro,

      Please note that Azure Functions have had a big overhaul since writing this post. I used the “Experimental” PowerShell support in Azure Functions v1. Nowadays there is Azure Functions v2 and recently released with support for PowerShell Core in Public Preview. I’m expecting it works differently.

      Regards,

      John

  5. Awesome blog and thanks very much for all your help John.

    Got this working with v2 using the code below.

    Had to generate a password using the function as it’s not available in core. Removed some characters I don’t like šŸ™‚

    ###Azure Function v2####

    using namespace System.Net

    param($Request)

    $keyVaultName = “YOUR KEY VAULT”
    $computer = $request.body.keyname
    write-host “Attempting to connect to Key Vault using MSI”
    # Get Azure Key Vault Access Token using the Function’s Managed Service Identity

    # Azure Key Vault resource to obtain access token
    $vaultTokenUri = ‘https://vault.azure.net’
    $apiVersion = ‘2017-09-01’

    # Get Azure Key Vault Access Token using the Function’s Managed Service Identity
    $authToken = Invoke-RestMethod -Method Get -Headers @{ ‘Secret’ = $env:MSI_SECRET } -Uri “$($env:MSI_ENDPOINT)?resource=$vaultTokenUri&api-version=$apiVersion”

    # Use Azure Key Vault Access Token to create Authentication Header
    $authHeader = @{ Authorization = “Bearer $($authToken.access_token)” }

    write-host “Setting Random Password”

    function new-password{

    $Alphabets = ‘a,b,c,d,e,f,g,h,i,j,k,m,n,p,q,r,t,u,v,w,x,y,z’
    $numbers = 2..9
    $specialCharacters = ‘!,@,#,$,%,&,*,?,+’
    $array = @()
    $array += $Alphabets.Split(‘,’) | Get-Random -Count 6
    $array[0] = $array[0].ToUpper()
    $array[-1] = $array[-1].ToUpper()
    $array += $numbers | Get-Random -Count 3
    $array += $specialCharacters.Split(‘,’) | Get-Random -Count 3
    ($array | Get-Random -Count $array.Count) -join “”
    }

    $password = new-password

    # Generate a new body to set a secret in the Azure Key Vault
    $body = $request.body | Select-Object -Property * -ExcludeProperty keyName

    # Append the random password to the new body
    $body | Add-Member -NotePropertyName value -NotePropertyValue “$password”

    # Convert the body to JSON
    $body = $body | ConvertTo-Json

    # Azure Key Vault Uri to set a secret
    Write-host “Creating string to key vault”
    $vaultSecretUri = “https://$keyVaultName.vault.azure.net/secrets/$($request.Body.keyName)/?api-version=2016-10-01”

    # Set the secret in Azure Key Vault
    try{
    write-host “Setting secret in Azure Key Vault”
    $null = Invoke-RestMethod -Method PUT -Body $body -Uri $vaultSecretUri -ContentType ‘application/json’ -Headers $authHeader

    # Associate values to output bindings by calling ‘Push-OutputBinding’.
    Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    Body = $password })
    }
    catch{$error[0].errordetails.message}

    1. Hi Bally Singh,

      Thank you for your comment and sharing your code. Great that youā€™ve got it working with v2. I will try it out some time and update the post accordingly.

      Regards,

      John

    2. Hi Bally.

      I am using this code within my Azure function. However, when testing with the body element of the NewLocalAdmin file, there is no output being generated.

      Any ideas?

      1. Hi Mark,

        I noticed the same but think it has to do with the formatting the WordPress does in the comment. I’ve just released updated scripts on GitHub, using some of Bally’s code.

        Would be glad to know if it works out now!

        https://github.com/jseerden/SLAPS

        Will update the blog post accordingly when I find some time to do so!

        Best regards,

        John

        1. Thanks John.

          I have reverted back to your original code for the PS function, as funnily enough after refreshing the functions page within Azure a couple of times, the option reappeared for ‘Experimental Language Support’. It was not visible initially.

          So… I am using the ‘Set-KeyVaultSecret’ script from your article for the function, and the test within the function now generates a password without any errors. The problem is now relating to the ‘New-LocalAdmin’ client-side script. It fails, with various 401 (unauthorised) errors within the log, and I can see that the password has not been passed to the client as the $password variable is null.

          I’ve taken the script from Github and updated it, I’ll see what happens šŸ™‚

  6. Do you have this on Github by chance? I think theres a large option for the community to help expand this and bug fix. Such as the ability to add a scheduled task creation to run this at X date.

    1. Hi,

      I’ve managed the password rotation packaging the script as a win32 application, the detection script detects whether or not the password is to old.
      Next step is to handle passwords that were used.

      I’ll share on my github when it’s done and I’ve removed all sensible information.

    2. Hi Corey,

      Would be awesome if the community picks this up too! I’m seeing increased activity on this blog post, so planning an update soon.

      Prior to updating the post, I just released updated scripts on GitHub (https://github.com/jseerden/SLAPS), using some of Bally’s code, that should work with a v2 Azure Function App running PowerShell Core (which is in Preview).

      Best regards,

      John

  7. Hello John,

    Thanks for all of your hard work on this. I’m using Bally’s code to get this working and am able to test and execute the Set-KeyVaultSecret function successfully from within Azure, however, when trying to run the local ps1 script, I’m being returned an empty string value. I’m sure I’m missing something simple?

    1. Hi Nick,

      I experienced the same issue and believe it might have to do something with the formatting in WordPress.

      I’ve just released updated scripts on GitHub (https://github.com/jseerden/SLAPS), using some of Bally’s code, that should work with a v2 Azure Function App running PowerShell Core (which is in Preview).

      Would be glad to know if it works out now!

      Best regards,

      John

  8. Was getting the same error as NKoro. “Exception: No parameter defined in the script or function for the input binding ā€˜Requestā€™.” Any update there by chance?

    Thanks!

  9. This is awesome thank you. But I think these instructions are outdated correct? I have ran into some snags where for example i cant find the Powershell Experimental language as an option?

  10. If you have any ARM devices, be sure to also add logic to check for them. Right now you get a powershell recursive loop if you run it as is.

    Example:
    if ((gwmi -Class Win32_OperatingSystem ).OSArchitecture -like “*ARM*”)
    {
    #ARM devices are not supported
    Write-Output “ARM Devices are not supported for this script and must be configured manually”
    }

    1. Hi Michael,

      Agreed, at least if you are targetting the PowerShell scripts to users. If you would be assigning it to devices you should exclude a dynamic group that includes all ARM devices.

      Best regards,

      John

  11. This is an awesome solution, but my concern is that this script will only run once per user if deployed via Intune. Have you tested using Azure Automation DSC, so that it runs every 30 minutes no matter whom logs in…like LAPS does?

    1. Hi,

      The script will probably run once per user, that’s true. I haven’t worked with Azure Automation DSC on Windows 10 clients.

      Another way to accomplish rotation with just Intune is to repackage the script as a Win32 app, and include some logic that the detection rule can check when the admin credential was created/updated. As detections run every hour with the IntuneManagementExtension, and when it fails that will trigger a reinstall, periodical rotation can be achieved like that.

      Best regards,

      John

  12. I’m followed the updated tutorial from Tim Hermie and the scripts from https://github.com/jseerden/SLAPS, the random password generates, but it doesnt update the secrets in key vault, the error is
    2020-04-08T21:26:29 Welcome, you are now connected to log-streaming service. The default timeout is 2 hours. Change the timeout with the App Setting SCM_LOGSTREAM_TIMEOUT (in seconds).
    2020-04-08T21:27:29 No new trace in the past 1 min(s).
    2020-04-08T21:28:29 No new trace in the past 2 min(s).
    2020-04-08T21:29:29 No new trace in the past 3 min(s).
    2020-04-08T21:30:29 No new trace in the past 4 min(s).
    2020-04-08T21:31:29 No new trace in the past 5 min(s).
    2020-04-08T21:32:18.621 [Information] Executing ‘Functions.set-keyvaultsecret’ (Reason=’This function was programmatically called via the host APIs.’, Id=bb3f1e71-56db-48bf-82d6-04c8ef7fb462)
    2020-04-08T21:32:20.183 [Information] Managed dependency download is in progress, function execution will continue when it’s done.
    2020-04-08T21:33:29 No new trace in the past 1 min(s).
    2020-04-08T21:34:29 No new trace in the past 2 min(s).
    2020-04-08T21:35:29 No new trace in the past 3 min(s).
    2020-04-08T21:36:02.364 [Error] ERROR: Invoke-RestMethod : {“error”:{“code”:”MethodNotAllowed”,”message”:”HTTP PUT not allowed”}}
    At D:\home\site\wwwroot\set-keyvaultsecret\run.ps1:49 char:9
    + $null = Invoke-RestMethod -Method PUT -Body $body -Uri $vaultSecretUr …
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (Method: PUT, Reques\u2026application/json
    }:HttpRequestMessage) [Invoke-RestMethod], HttpResponseException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
    Script stack trace:
    at , D:\home\site\wwwroot\set-keyvaultsecret\run.ps1: line 49

    Microsoft.PowerShell.Commands.HttpResponseException: Response status code does not indicate success: 405 (Method Not Allowed).
    at System.Management.Automation.MshCommandRuntime.ThrowTerminatingError(ErrorRecord errorRecord)

    Microsoft.Azure.WebJobs.Script.Workers.Rpc.RpcException : Result: ERROR: Invoke-RestMethod : {“error”:{“code”:”MethodNotAllowed”,”message”:”HTTP PUT not allowed”}}
    At D:\home\site\wwwroot\set-keyvaultsecret\run.ps1:49 char:9
    + $null = Invoke-RestMethod -Method PUT -Body $body -Uri $vaultSecretUr …
    +

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : InvalidOperation: (Method: PUT, Reques\u2026application/json
    }:HttpRequestMessage) [Invoke-RestMethod], HttpResponseException
    + FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand
    Script stack trace:
    at , D:\home\site\wwwroot\set-keyvaultsecret\run.ps1: line 49

    Microsoft.PowerShell.Commands.HttpResponseException: Response status code does not indicate success: 405 (Method Not Allowed).
    at System.Management.Automation.MshCommandRuntime.ThrowTerminatingError(ErrorRecord errorRecord)

    Exception: Response status code does not indicate success: 405 (Method Not Allowed).
    Stack: at System.Management.Automation.MshCommandRuntime.ThrowTerminatingError(ErrorRecord errorRecord)
    2020-04-08T21:36:02.946 [Information] Executed ‘Functions.set-keyvaultsecret’ (Succeeded, Id=bb3f1e71-56db-48bf-82d6-04c8ef7fb462)

    what am i missing?

    1. Hi mihaii,

      Hope you have resolved this issue in the meantime.

      It seems to me that the Azure Functions Managed Identity Service Principal doesn’t have the necessary permissions to put credentials in the Azure Key Vault.

      Best regards,

      John

  13. Hey mate, I do use it :).
    I managed to solve the first error I have got but now I have another one.

    When I run the test, I get the password but it does not write in the vault… I get an error:

    [Error] ERROR: Invoke-RestMethod : {“error”:{“code”:”MethodNotAllowed”,”message”:”HTTP PUT not allowed”}}

    1. Hi Anton, did you copy/paste the test body? If so, you may want to overwrite (really type them yourself) ALL the double quotes in that body and try again…

    2. I’m having the same error.

      ERROR: Invoke-RestMethod : {“error”:{“code”:”MethodNotAllowed”,”message”:”HTTP PUT not allowed”}}

      I have confirmed that the vault access policy is set to allow the function, so I’m not sure what’s left to adjust?

    3. Having the same issue. Retyped the double quotes in the new-localadmin.ps1 file. Still no luck. Permissions are set correctly as well. If I run the test it works, just not from the powershell script. Any luck solving this issue yet?

    4. Hi Anthon

      Change:
      $password = Invoke-RestMethod -Uri $uri -Method POST -Body $body -ErrorAction Stop

      Into:
      $password = Invoke-RestMethod -Uri $uri -Method POST -Body $body -ContentType “application/json” -ErrorAction Stop

      Cheers from Belgium šŸ˜‰

    1. Hi Derek,

      If a Local Admin account was created with this script, you will be able to log on to the device with those credentials when no internet connectivity is available.

      Best regards,

      John

  14. I have the same error as well.
    Invoke-RestMethod : {“error”:{“code”:”MethodNotAllowed”,”message”:”HTTP PUT not allowed”}}

Leave a Reply

Your email address will not be published. Required fields are marked *