gpt4 book ai didi

c# - 从 C# 应用程序调用 azure powershell cmdlet 失败

转载 作者:行者123 更新时间:2023-11-30 18:35:45 25 4
gpt4 key购买 nike

我试图自动化部署到 azure 云的过程。我的 powershell 脚本可以做到这一点,当从 azure powershell 命令行执行它时,它的工作方式就像一个魅力。当我尝试从 C# 应用程序调用相同的脚本时,它失败了。

这是我的代码:

  internal  void RunPowerShellScript(string scriptPath, Dictionary<string, string> arguments)
{
RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();
Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);
runspace.Open();
RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);
Pipeline pipeline = runspace.CreatePipeline();
//Here's how you add a new script with arguments
Command myCommand = new Command(scriptPath, true);
foreach (var argument in arguments)
{
myCommand.Parameters.Add(new CommandParameter(argument.Key, argument.Value));
}
pipeline.Commands.Add(myCommand);
var results = pipeline.Invoke();
foreach (var psObject in results)
{
_view.PrintOutput(psObject.ToString());
}
}

我也关注了其他线程,例如这个:Execute PowerShell Script from C# with Commandline Arguments这个: passing parameters to powershell from c#

但似乎没有任何作用。我收到以下错误:

无法验证参数“PublishSettingsFile”的参数。参数为 null 或为空。提供一个不为 null 或空的参数,然后重试该命令。

脚本:

Param(  $serviceName = "",
$storageAccountName = "",
$packageLocation = "",
$cloudConfigLocation = "",
$environment = "",
$deploymentLabel = "",
$timeStampFormat = "g",
$alwaysDeleteExistingDeployments = 1,
$enableDeploymentUpgrade = 1,
$selectedsubscription = "default",
$subscriptionDataFile = ""
)

function Publish()
{
#Set-ExecutionPolicy RemoteSigned
Set-AzureSubscription -SubscriptionName "Windows Azure MSDN – Visual Studio Professional" -CurrentStorageAccount $storageAccountName
$deployment = Get-AzureDeployment -ServiceName $serviceName -Slot $slot -ErrorVariable a -ErrorAction silentlycontinue
if ($a[0] -ne $null)
{
Write-Output "$(Get-Date –f $timeStampFormat) - No deployment is detected. Creating a new deployment. "
}
#check for existing deployment and then either upgrade, delete + deploy, or cancel according to $alwaysDeleteExistingDeployments and $enableDeploymentUpgrade boolean variables
if ($deployment.Name -ne $null)
{
switch ($alwaysDeleteExistingDeployments)
{
1
{
switch ($enableDeploymentUpgrade)
{
1 #Update deployment inplace (usually faster, cheaper, won't destroy VIP)
{
Write-Output "$(Get-Date –f $timeStampFormat) - Deployment exists in $servicename. Upgrading deployment."
UpgradeDeployment
}
0 #Delete then create new deployment
{
Write-Output "$(Get-Date –f $timeStampFormat) - Deployment exists in $servicename. Deleting deployment."
DeleteDeployment
CreateNewDeployment

}
} # switch ($enableDeploymentUpgrade)
}
0
{
Write-Output "$(Get-Date –f $timeStampFormat) - ERROR: Deployment exists in $servicename. Script execution cancelled."
exit
}
} #switch ($alwaysDeleteExistingDeployments)
} else {
CreateNewDeployment
}
SwapVip
}
function DeleteDeployment()
{
write-progress -id 2 -activity "Deleting Deployment" -Status "In progress"
Write-Output "$(Get-Date –f $timeStampFormat) - Deleting Deployment: In progress"

#WARNING - always deletes with force
$removeDeployment = Remove-AzureDeployment -Slot $slot -ServiceName $serviceName -Force

write-progress -id 2 -activity "Deleting Deployment: Complete" -completed -Status $removeDeployment
Write-Output "$(Get-Date –f $timeStampFormat) - Deleting Deployment: Complete"
}

function StartInstances()
{
write-progress -id 4 -activity "Starting Instances" -status "In progress"
Write-Output "$(Get-Date –f $timeStampFormat) - Starting Instances: In progress"

$deployment = Get-AzureDeployment -ServiceName $serviceName -Slot $slot
$runstatus = $deployment.Status

if ($runstatus -ne 'Running')
{
$run = Set-AzureDeployment -Slot $slot -ServiceName $serviceName -Status Running
}
$deployment = Get-AzureDeployment -ServiceName $serviceName -Slot $slot
$oldStatusStr = @("") * $deployment.RoleInstanceList.Count

while (-not(AllInstancesRunning($deployment.RoleInstanceList)))
{
$i = 1
foreach ($roleInstance in $deployment.RoleInstanceList)
{
$instanceName = $roleInstance.InstanceName
$instanceStatus = $roleInstance.InstanceStatus

if ($oldStatusStr[$i - 1] -ne $roleInstance.InstanceStatus)
{
$oldStatusStr[$i - 1] = $roleInstance.InstanceStatus
Write-Output "$(Get-Date –f $timeStampFormat) - Starting Instance '$instanceName': $instanceStatus"
}

write-progress -id (4 + $i) -activity "Starting Instance '$instanceName'" -status "$instanceStatus"
$i = $i + 1
}

sleep -Seconds 1

$deployment = Get-AzureDeployment -ServiceName $serviceName -Slot $slot
}

$i = 1
foreach ($roleInstance in $deployment.RoleInstanceList)
{
$instanceName = $roleInstance.InstanceName
$instanceStatus = $roleInstance.InstanceStatus

if ($oldStatusStr[$i - 1] -ne $roleInstance.InstanceStatus)
{
$oldStatusStr[$i - 1] = $roleInstance.InstanceStatus
Write-Output "$(Get-Date –f $timeStampFormat) - Starting Instance '$instanceName': $instanceStatus"
}

$i = $i + 1
}

$deployment = Get-AzureDeployment -ServiceName $serviceName -Slot $slot
$opstat = $deployment.Status

write-progress -id 4 -activity "Starting Instances" -completed -status $opstat
Write-Output "$(Get-Date –f $timeStampFormat) - Starting Instances: $opstat"
}
function AllInstancesRunning($roleInstanceList)
{
foreach ($roleInstance in $roleInstanceList)
{
if ($roleInstance.InstanceStatus -ne "ReadyRole")
{
return $false
}
}

return $true
}
function SwapVip()
{
Write-Output "$(Get-Date –f $timeStampFormat) - Swap production and staging for $servicename."
Move-AzureDeployment -ServiceName $servicename
}
function CreateNewDeployment()
{
write-progress -id 3 -activity "Creating New Deployment" -Status "In progress"
Write-Output "$(Get-Date –f $timeStampFormat) - Creating New Deployment: In progress"

$opstat = New-AzureDeployment -Slot $slot -Package $packageLocation -Configuration $cloudConfigLocation -label $deploymentLabel -ServiceName $serviceName

$completeDeployment = Get-AzureDeployment -ServiceName $serviceName -Slot $slot
$completeDeploymentID = $completeDeployment.deploymentid

write-progress -id 3 -activity "Creating New Deployment" -completed -Status "Complete"
Write-Output "$(Get-Date –f $timeStampFormat) - Creating New Deployment: Complete, Deployment ID: $completeDeploymentID"

StartInstances
}

function UpgradeDeployment()
{
write-progress -id 3 -activity "Upgrading Deployment" -Status "In progress"
Write-Output "$(Get-Date –f $timeStampFormat) - Upgrading Deployment: In progress"

# perform Update-Deployment
$setdeployment = Set-AzureDeployment -Upgrade -Slot $slot -Package $packageLocation -Configuration $cloudConfigLocation -label $deploymentLabel -ServiceName $serviceName -Force

$completeDeployment = Get-AzureDeployment -ServiceName $serviceName -Slot $slot
$completeDeploymentID = $completeDeployment.deploymentid

write-progress -id 3 -activity "Upgrading Deployment" -completed -Status "Complete"
Write-Output "$(Get-Date –f $timeStampFormat) - Upgrading Deployment: Complete, Deployment ID: $completeDeploymentID"
}
Import-Module Azure
$pubsettings = $subscriptionDataFile
Import-AzurePublishSettingsFile $pubsettings
Set-AzureSubscription -CurrentStorageAccount $storageAccountName -SubscriptionName $selectedsubscription

#set remaining environment variables for Azure cmdlets
$subscription = Get-AzureSubscription $selectedsubscription
$subscriptionname = $subscription.subscriptionname
$subscriptionid = $subscription.subscriptionid
$slot = $environment


Write-Output "$(Get-Date –f $timeStampFormat) - Azure Cloud Service deploy script started."
Write-Output "$(Get-Date –f $timeStampFormat) - Preparing deployment of $deploymentLabel for $subscriptionname with Subscription ID $subscriptionid."

Publish

$deployment = Get-AzureDeployment -slot $slot -serviceName $servicename
$deploymentUrl = $deployment.Url

Write-Output "$(Get-Date –f $timeStampFormat) - Created Cloud Service with URL $deploymentUrl."
Write-Output "$(Get-Date –f $timeStampFormat) - Azure Cloud Service deploy script finished."

最佳答案

我相信您传递publishsettings文件的方式导致了这个问题。传递publishsettings文件时,您必须添加引号,如果没有引号,您将遇到异常。

以下是基于您的代码的代码,我通过使用 (\") 传递带有引号的发布设置文件来测试它,它工作正常:

private void button1_Click(object sender, EventArgs e)
{
Dictionary<string, string> myDict= new Dictionary<string, string>();
myDict.Add("-subscriptionDataFile", "\"C:\\InstallBox\\asc.publishsettings\"");
RunPowerShellScript("C:\\InstallBox\\testcode.ps1", myDict);
}

internal void RunPowerShellScript(string scriptPath, Dictionary<string, string> arguments)
{
RunspaceConfiguration runspaceConfiguration = RunspaceConfiguration.Create();
Runspace runspace = RunspaceFactory.CreateRunspace(runspaceConfiguration);
runspace.Open();
RunspaceInvoke scriptInvoker = new RunspaceInvoke(runspace);
Pipeline pipeline = runspace.CreatePipeline();
//Here's how you add a new script with arguments
Command myCommand = new Command(scriptPath);
foreach (var argument in arguments)
{
myCommand.Parameters.Add(new CommandParameter(argument.Key, argument.Value));
}
pipeline.Commands.Add(myCommand);
var results = pipeline.Invoke();
foreach (var psObject in results)
{
.........
}
}

我的 testcode.ps1 如下:

Param(  [string]$subscriptionDataFile)
Import-Module Azure
Import-AzurePublishSettingsFile subscriptionDataFile
Get-AzureSubscription

为了确保我可以看到您的问题,如果我将字典键值对更改为如下(不带引号),我会得到与您描述的完全相同的错误:

myDict.Add("-subscriptionDataFile", "C:\\InstallBox\\asc.publishsettings");

所以传递PublishSettings文件的正确方法如下:

myDict.Add("-subscriptionDataFile", "\"C:\\InstallBox\\asc.publishsettings\"");

关于c# - 从 C# 应用程序调用 azure powershell cmdlet 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14568665/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com