Azure VM,powershell中的扩展脚本,如何作为参数传递json对象

问题描述 投票:0回答:1

我在 Powershell 中有一个脚本,我想将其作为 Azure VM 中的脚本扩展运行。该脚本应该下载各种东西,并且配置会将其作为对象输入。我已经坐了两天了,我被困住了。也许你有一个可行的想法?我在将对象从 json 文件传递给它时遇到问题。 错误:

 at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(Newtonsoft.Json.JsonWriter, System.Object, Newtonsoft.Json.Serialization.JsonObjectContract, Newtonsoft.Json.Serialization.JsonProperty, Newtonsoft.Json.Serialization.JsonContainerContract, Newtonsoft.Json.Serialization.JsonProperty)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(Newtonsoft.Json.JsonWriter, System.Object, Newtonsoft.Json.Serialization.JsonObjectContract, Newtonsoft.Json.Serialization.JsonProperty, Newtonsoft.Json.Serialization.JsonContainerContract, Newtonsoft.Json.Serialization.JsonProperty)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(Newtonsoft.Json.JsonWriter, System.Object, Newtonsoft.Json.Serialization.JsonObjectContract, Newtonsoft.Json.Serialization.JsonProperty, Newtonsoft.Json.Serialization.JsonContainerContract, Newtonsoft.Json.Serialization.JsonProperty)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(Newtonsoft.Json.JsonWriter, System.Object, Newtonsoft.Json.Serialization.JsonObjectContract, Newtonsoft.Json.Serialization.JsonProperty, Newtonsoft.Json.Serialization.JsonContainerContract, Newtonsoft.Json.Serialization.JsonProperty)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(Newtonsoft.Json.JsonWriter, System.Object, Newtonsoft.Json.Serialization.JsonObjectContract, Newtonsoft.Json.Serialization.JsonProperty, Newtonsoft.Json.Serialization.JsonContainerContract, Newtonsoft.Json.Serialization.JsonProperty)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(Newtonsoft.Json.JsonWriter, System.Object, Newtonsoft.Json.Serialization.JsonObjectContract, Newtonsoft.Json.Serialization.JsonProperty, Newtonsoft.Json.Serialization.JsonContainerContract, Newtonsoft.Json.Serialization.JsonProperty)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(Newtonsoft.Json.JsonWriter, System.Object, Newtonsoft.Json.Serialization.JsonObjectContract, Newtonsoft.Json.Serialization.JsonProperty, Newtonsoft.Json.Serialization.JsonContainerContract, Newtonsoft.Json.Serialization.JsonProperty)
   at Newtonsoft.Json.Serialization.JsonSerializerInternalWriter.SerializeObject(Newtonsoft.Json.JsonWriter, System.Object, Newtonsoft.Json.Serialization.JsonObjectContract, Newtonsoft.Json.Serialization.JsonProperty, Newtonsoft.Json.Serialization.JsonContainerContract,
at System.Management.Automation.PipelineOps.InvokePipeline(System.Object, Boolean, System.Management.Automation.CommandParameterInternal[][], System.Management.Automation.Language.CommandBaseAst[], System.Management.Automation.CommandRedirection[][], System.Management.Automation.Language.FunctionContext)
   at System.Management.Automation.Interpreter.ActionCallInstruction`6[[System.__Canon, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Boolean, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].Run(System.Management.Automation.Interpreter.InterpretedFrame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(System.Management.Automation.Interpreter.InterpretedFrame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(System.Management.Automation.Interpreter.InterpretedFrame)
   at System.Management.Automation.Interpreter.Interpreter.Run(System.Management.Automation.Interpreter.InterpretedFrame)
   at System.Management.Automation.Interpreter.LightLambda.RunVoid1[[System.__Canon, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](System.__Canon)
   at System.Management.Automation.PSScriptCmdlet.RunClause(System.Action`1<System.Management.Automation.Language.FunctionContext>, System.Object, System.Object)
   at System.Management.Automation.CommandProcessorBase.Complete()
   at System.Management.Automation.CommandProcessorBase.DoComplete()
   at System.Management.Automation.Internal.PipelineProcessor.DoCompleteCore(System.Management.Automation.CommandProcessorBase)
   at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(System.Object)
   at System.Management.Automation.PipelineOps.InvokePipeline(System.Object, Boolean, System.Management.Automation.CommandParameterInternal[][], System.Management.Automation.Language.CommandBaseAst[], System.Management.Automation.CommandRedirection[][], System.Management.Automation.Language.FunctionContext)
   at System.Management.Automation.Interpreter.ActionCallInstruction`6[[System.__Canon, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.Boolean, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].Run(System.Management.Automation.Interpreter.InterpretedFrame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(System.Management.Automation.Interpreter.InterpretedFrame)
   at System.Management.Automation.Interpreter.EnterTryCatchFinallyInstruction.Run(System.Management.Automation.Interpreter.InterpretedFrame)
   at System.Management.Automation.Interpreter.Interpreter.Run(System.Management.Automation.Interpreter.InterpretedFrame)
   at System.Management.Automation.Interpreter.LightLambda.RunVoid1[[System.__Canon, System.Private.CoreLib, Version=8.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](System.__Canon)
   at System.Management.Automation.DlrScriptCommandProcessor.RunClause(System.Action`1<System.Management.Automation.Language.FunctionContext>, System.Object, System.Object)
   at System.Management.Automation.DlrScriptCommandProcessor.Complete()
   at System.Management.Automation.CommandProcessorBase.DoComplete()
   at System.Management.Automation.Internal.PipelineProcessor.DoCompleteCore(System.Management.Automation.CommandProcessorBase)
   at System.Management.Automation.Internal.PipelineProcessor.SynchronousExecuteEnumerate(System.Object)
   at System.Management.Automation.Runspaces.LocalPipeline.InvokeHelper()
   at System.Management.Automation.Runspaces.LocalPipeline.InvokeThreadProc()
   at System.Management.Automation.Runspaces.PipelineThread.WorkerProc()
   at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)

[process exited with code 3221225725 (0xc00000fd)]
You can now close this terminal with Ctrl+D, or press Enter to restart.

Json 文件:

{
  "parameters": {
    "keyVault": {
      "value": {
        "name": "kv-name",
        "subscriptionId": "00000-0000-0000-0000"
      }
    },
    "certificates": {
      "value": [
        {
          "name": "application-certificate",
          "SaveTo": "C:\\Temp2\\"
        },
        {
          "name": "client-certificate",
          "SaveTo": "C:\\Temp\\"
        }
      ]
    },
    "secrets": {
      "value": [
        {
          "name": "secret1",
          "secretName": "secret1"
        },
        {
          "name": "secret2",
          "secretName": "mysecret2"
        },
        {
          "name": "Save certificate password",
          "secretName": "certificatePassword"
        }
      ]
    },
    "configCentralUri": {
      "value": "https://configcentral.adeo.local"
    }
  }
}

创建虚拟机的 PowerShell 脚本:

[CmdletBinding()]
param
(
  [Parameter()]
  [string]$VMRGName = 'rg-change-me', 
  $Location = 'westeurope',
  $VMName = 'myvm',
  [Parameter(Mandatory = $false)]
  $Object
)
$blobSasUrl = 'https://....'
$blobName = 'myscript.ps1'

$customScriptParam = @{
  ResourceGroupName  = $VMRGName
  Location           = $Location
  VMName             = $VMName
  Name               = 'ConfigurationScript'
  Publisher          = 'Microsoft.Compute'
  ExtensionType      = 'CustomScriptExtension'
  TypeHandlerVersion = '1.1'
  Settings           = @{
    'scriptBlobSasUri' = $blobSasUrl
    'commandToExecute' = "powershell -ExecutionPolicy Unrestricted -File $blobName -config '$Object'"
  }
}
Set-AzVMExtension @customScriptParam

我最后的行动:

$config = gc .\parameters.json | ConvertFrom-Json -Depth 10
$configRAW = ($config |  convertto-json -Depth 10 -Compress).replace('"','\"')
.\createVM.ps1 -Object $configRAW

我已经没有主意了,我向贵族社区寻求帮助

azure powershell azure-powershell azure-vm-templates azure-vm-extension
1个回答
0
投票

Azure VM,powershell中的扩展脚本,如何作为参数传递json对象

您收到的错误是由于

JSON
对象被序列化并传递给
PowerShell script

您可以使用下面的

PowerShell script
JSON
文件将 JSON 对象从 Azure 存储帐户传递到脚本中

myscript.ps1

[CmdletBinding()]
param (
    [string]$configFile
)

$logFile = "C:\Temp\script.log"
if (-not (Test-Path "C:\Temp")) { New-Item -ItemType Directory -Path "C:\Temp" }

function Log {
    param([string]$message)
    Add-Content -Path $logFile -Value "$(Get-Date) - $message"
}

try {
    Log "Starting script execution."
    $config = Get-Content $configFile | ConvertFrom-Json
    Log "Config loaded successfully: $(ConvertTo-Json $config -Depth 10)"
} catch {
    Log "Error: $_"
}

参数.json

{
  "parameters": {
    "keyVault": {
      "value": {
        "name": "kv-name",
        "subscriptionId": "00000-0000-0000-0000"
      }
    },
    "certificates": {
      "value": [
        {
          "name": "application-certificate",
          "SaveTo": "C:\\Temp2\\"
        },
        {
          "name": "client-certificate",
          "SaveTo": "C:\\Temp\\"
        }
      ]
    },
    "secrets": {
      "value": [
        {
          "name": "secret1",
          "secretName": "secret1"
        },
        {
          "name": "secret2",
          "secretName": "mysecret2"
        },
        {
          "name": "Save certificate password",
          "secretName": "certificatePassword"
        }
      ]
    },
    "configCentralUri": {
      "value": "https://configcentral.adeo.local"
    }
  }
}

确保将 parameters.jsonmyscript.ps1 文件上传到 Azure 存储并从特定 blob 获取 SAS URL

enter image description here

从 blob 中为 parameters.json 生成 SAS URL,就像为 myscript.ps1* blob 生成 SAS URL 一样。

enter image description here

blobSasUrl 生成

enter image description here

虚拟机扩展脚本

$blobSasUrl = "https://venkatstoragetestdemo.blob.core.windows.net/venkat?sp=racwdli&st=2024-11-20T10:30:05Z&fffffffffffdjfjf:30:05Z&sv=2022-11-02&sr=c&sig=ghghghghggOpN6sqEYvpW17sUe0jA50JGP4bauvJkok%3D"

$jsonSasUrl = "https://venkatstoragetestdemo.blob.core.windows.net/venkat/parameters.json?sp=racwdyt&st=2024-11-20T10:32:0221102&sr=b&sig=FSXGWjNLSgOWTzrsi8lkSDvCp9fTp0s%3D"

$scriptSasUrl = "https://venkatstoragetestdemo.blob.core.windows.net/venkat/myscript.ps1?sp=racwdyt&st=2024-11-20T10:31:43Z&sefKSPprtjI%3D"

Set-AzVMExtension -ResourceGroupName "container-RG" -VMName "Container-VM" -Name "ConfigurationScript" `
    -Publisher "Microsoft.Compute" -ExtensionType "CustomScriptExtension" -TypeHandlerVersion "1.10" `
    -Settings @{
        "scriptBlobSasUri" = $blobSasUrl
        "commandToExecute" = "powershell -ExecutionPolicy Unrestricted -File myscript.ps1 -configFile parameters.json"
    } `
    -ProtectedSettings @{
        "fileUris" = @($scriptSasUrl, $jsonSasUrl) 
    }

输出

enter image description here

运行脚本后,myscript.ps1parameters.json文件已从存储帐户下载到虚拟机

enter image description here

创建虚拟机扩展后,脚本日志文件已在虚拟机上创建。

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.