繁体   English   中英

Azure PowerShell 运行手册:Invoke-RestMethod 的 InFile 标志未按预期工作

[英]Azure PowerShell runbook: -InFile flag of Invoke-RestMethod not working as intended

我正在创建一个 Azure 运行手册脚本,该脚本获取图像,然后通过 http 再次发送它以更新特定公司用户的个人资料图片。 相关文档说,运行 runbook 的工作人员有一个可访问的临时存储,我确实可以在那里看到文件下载,但是当通过 -InFile 指定其路径时,它一直返回 400 并且在 postman 上它工作得很好,所以通过我自己电脑的 PowerShell 在本地进行。 这是代码:

## 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 上它一直返回相同的错误:

在此处输入图像描述

以下是过去运行的一些额外调试输出,可以确认文件存在:

在此处输入图像描述

要回答我认为可能首先想知道的问题:在 Azure AD 上,auth2.0 令牌及其各自的应用程序已配置为允许代表其他人更新个人资料图片。 在我自己的机器上,我可以在本地更改同事的照片。

我使用你的脚本,它在我这边的 Azure 自动化运行手册中运行良好。

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

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

$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'

让我知道它是否有效。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM