Azure PowerShell Runbook:Invoke-RestMethod的-InFile标志未按预期工作 [英] Azure PowerShell runbook: -InFile flag of Invoke-RestMethod not working as intended

查看:61
本文介绍了Azure PowerShell Runbook:Invoke-RestMethod的-InFile标志未按预期工作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在创建一个Azure运行簿脚本,该脚本将获取图像,然后再次通过http发送它以更新特定公司用户的个人资料图片.相关文档说,运行Runbook的工作程序具有一个可访问的临时存储,的确可以看到文件的下载,但是当通过-InFile指定其路径时,它会继续返回400,而在邮递员上,它运行良好,因此通过我自己的计算机的PowerShell在本地执行.这是代码:

I'm creating an Azure runbook script that fetches an image and then sends it again via http to update a specific company user's profile picture. The relevant documentation says that the worker that runs the runbook has a temporary storage that is accessible and indeed I can see the file downloads there, but then when specifying its path via -InFile it keeps returning a 400 and on postman it works perfectly, so does locally via my own computer's PowerShell. Here's the code:

## Begin fetching auth2.0 token ##

## Fetch user

$boundary = [System.Guid]::NewGuid().ToString(); 
$LF = "`r`n";

# Because the workers run an earlier version of PowerShell I had to declare the form in this 
jibberish way, as per another stackoverflow thread. However this works and the auth2.0 is retrieved.

$bodyLines = ( 
    "--$boundary",
    "Content-Disposition: form-data; name=`"grant_type`"$LF",
    "client_credentials$LF",
    "--$boundary",
    "Content-Disposition: form-data; name=`"client_id`"$LF",
    "[client_id]$LF",
    "--$boundary",
    "Content-Disposition: form-data; name=`"scope`"$LF",
    "https://graph.microsoft.com/.default$LF",
    "--$boundary",
    "Content-Disposition: form-data; name=`"client_secret`"$LF",
    "[client_secret]$LF",
    "--$boundary--$LF" 
) -join $LF

$AuthTokenRequestHeaders = @{
    "Cache-Control" = "no-cache"
}

$AuthTokenResponse = Invoke-RestMethod 'https://login.microsoftonline.com/[company-name].onmicrosoft.com/oauth2/v2.0/token' -Method 'POST' -ContentType "multipart/form-data; boundary=`"$boundary`"" -Body $bodyLines -Headers $AuthTokenRequestHeaders

$authToken = $AuthTokenResponse.access_token

#### Finish token fetching ####


# Get user-specific Microsoft Object ID
$MsolCred = Get-AutomationPSCredential -Name "Office365"
Connect-MsolService -Credential $MsolCred -AzureEnvironment "AzureCloud"
$MsolUserId = (Get-MsolUser -UserPrincipalName $Email).ObjectId.Guid


#### Begin updating profile picture ####
$RequestHeader = @{
    "Authorization" = "Bearer $authToken"
    "Content-Type" = "image/jpeg"
}

# Look at contents on static OneDrive folder
$OneDriveFolderContents = (Invoke-RestMethod -Uri 'https://graph.microsoft.com/v1.0/drives/[drive-id]/items/[folder-id]/children' -Method Get -Headers $RequestHeader)

# Logic to look for the most recent file
$MostRecentFileDate = 0;
$MostRecentFileId = "";

foreach ($file in $OneDriveFolderContents.value) {

    if ($file.createdDateTime -gt $MostRecentFileDate) {
        $MostRecentFileDate = $file.createdDateTime
        $MostRecentFileId = $file.id
    }

}

# GET for most recent image
$restById = (Invoke-RestMethod -Uri "https://graph.microsoft.com/v1.0/drives/[drive-id]/items/$mostRecentFileId/content" -Method Get -Headers $RequestHeader -OutFile "profilepicture.jpeg") 


# This section was for debugging purposes. Checking if the file was downloaded correctly and its path in the runbook worker who's running the script. Because workers only have one randomly named folder and a folder named "diags" I just exclude the diags folder and look for it inside the temporary folder after finding its name
$var1 =  (Get-ChildItem -Path 'C:\Temp\' -Depth 2).Directory
$var2 = ""

foreach ($folder in $var1) {

    if ($folder.Name -ne "diags") {
        $var2 = $folder.Name
    }
    
}

Write-Output "Found folder named $var2 to use in path"

## End debugging section


$forinfile = "C:\Temp\$var2\profilepicture.jpeg"

# This confirms that the file is indeed there
Write-Output (Get-ChildItem -Path C:\Temp\ -Depth 2)

# PUT most recent image to the specific user
$userUrlString = "https://graph.microsoft.com/v1.0/users/" + $MsolUserId + '/photo/$value'

# This is the specific Invoke-RestMethod that returns a 400. Following are 4 different ones I tried with no success
Invoke-RestMethod -Uri $userUrlString -Method Put -Headers $RequestHeader -InFile "$forinfile"
Invoke-RestMethod -Uri $userUrlString -Method Patch -Headers $RequestHeader -InFile "profilepicture.jpeg"
Invoke-RestMethod -Uri $userUrlString -Method Put -Headers $RequestHeader -InFile "profilepicture.jpeg"
Invoke-RestMethod -Uri $userUrlString -Method Patch -Headers $RequestHeader -InFile "$forinfile"

该代码在我自己的计算机上可以正常运行,但是在Azure上,它始终返回相同的错误:

The code works perfectly on my own machine, but on Azure it keeps returning the same error:

以下是过去运行的其他一些调试输出,可以肯定地确认文件是否存在:

Here are some additional debugging outputs from past runs that confirm FOR SURE the file is there:

要回答我认为可能是第一件事,那就是:在Azure AD上,将auth2.0令牌及其相应的应用程序配置为允许代表其他人更新个人资料图片.在本地计算机上,我可以更改同事的照片.

To answer what I think may be the first thing wondered: on Azure AD the auth2.0 token and its respective application have been configured to allow a profile picture update on behalf of someone else. Locally on my own machine I was able to change a coworker's picture.

推荐答案

我使用了您的脚本,并且从我的角度来看,它在Azure自动化运行手册中也能正常工作.

I use your script and it works fine in Azure Automation Runbook from my side.

由于jpeg文件已成功下载,所以问题应该出在最后一次Graph调用上.

Since the jpeg file is successfully downloaded, the issue should lie on the last Graph call.

要解决此问题,您不需要使用:

To troubleshooting this issue, you don't need to use:

$MsolCred = Get-AutomationPSCredential -Name "Office365"
Connect-MsolService -Credential $MsolCred -AzureEnvironment "AzureCloud"
$MsolUserId = (Get-MsolUser -UserPrincipalName $Email).ObjectId.Guid
$userUrlString = "https://graph.microsoft.com/v1.0/users/" + $MsolUserId + '/photo/$value'

只需使用 $ userUrlString ="https://graph.microsoft.com/v1.0/users/"+ $ Email +'/photo/$ value'.

让我知道它是否有效.

这篇关于Azure PowerShell Runbook:Invoke-RestMethod的-InFile标志未按预期工作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆