3

Azureクラウドへのデプロイプロセスを自動化しようとしています。それを行う私のPowerShellスクリプトは、紺碧の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());
        }
    }

私は他のスレッドもフォローしました。たとえば、次のようなものです。コマンドライン引数を使用してC#からPowerShellスクリプトを実行し 、これはC#からPowerShellにパラメーターを渡します。

しかし、何も機能していないようです。次のエラーが発生します:

パラメータ'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."
4

1 に答える 1

0

私はあなたがpublishsettingsファイルを渡す方法が問題を引き起こしていると信じています。publishsettingsファイルを渡すときは、引用符を追加する必要があります。引用符がない場合は、例外が発生します。

以下はあなたのコードに基づくコードであり、(\ ")を使用して引用符付きのpublishsettingファイルを渡すことでテストしましたが、正常に動作します。

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\"");
于 2013-01-29T05:51:28.010 に答える