我有一个VS 2012 MVC 4 Web角色项目,在从启动cmd运行Set-ExecutionPolicy Unrestricted
之后,我成功地从角色的bin目录中调用了powershell脚本。该脚本包含一些azure cmdlet,当我在本地运行该项目时,脚本运行完美。但是,当我在Azure上发布项目时,脚本中的相同azure cmdlet不会运行。例如:
param([string]$websiteName="itudkcloudqwerdfs", [string]$serverLogin="user", [string]$serverPass="paSS123!@#", [string]$location="North Europe")
# Create new Website
#
$website = New-AzureWebsite -Location $location -Name $websiteName
if ($website -eq $null)
{
throw "Website creation error"
exit
}
在本地运行时成功创建Azure网站,但在发布并从云服务运行时抛出并退出。
当然我搜索了一个解决方案,我发现我必须将Azure Powershell预先安装到Web角色才能在那里运行Azure cmdlet。为此,我安装了Web平台安装程序4.5,将其命令行工具可执行文件与Microsoft.Web.PlatformInstaller dll和我的Azure publishsettings文件复制到我的Web角色的bin文件夹中,并创建了一个cmd,用于从webpicmd安装Azure Powershell Web角色的bin目录中的特殊文件夹,并在Web角色启动时导入我的publishsettings文件:
md "%~dp0appdata"
cd "%~dp0appdata"
cd..
reg add "hku\.default\software\microsoft\windows\currentversion\explorer\user shell folders" /v "Local AppData" /t REG_EXPAND_SZ /d "%~dp0appdata" /f
"%~dp0\WebpiCmd.exe" /Install /AcceptEula /Products:WindowsAzurePowershell /log:%~dp0WindowsAzurePowershell.log
reg add "hku\.default\software\microsoft\windows\currentversion\explorer\user shell folders" /v "Local AppData" /t REG_EXPAND_SZ /d %%USERPROFILE%%\AppData\Local /f
powershell Import-AzurePublishSettingsFile
exit /b 0
它仍然无法正常工作,因此我远程登录到该实例,以便亲自查看可能出错的内容。我尝试运行上面的cmd脚本,它需要启用.NET Framework 3.5功能,这对我来说很奇怪,因为实例已经默认启用了.NET 4.5功能(Windows Server 2012)。无论如何,我从服务器管理器启用它,脚本成功运行,没有错误。我打开了powershell,我测试了一些Azure cmdlet并且他们工作了。但是,即使在此之后,当我再次从Web应用程序调用脚本时,它仍然无法运行azure cmdlet并退出。
我错过了什么?为什么webpicmd需要.NET 3.5功能?有替代解决方案吗?
更新:在Gaurav的评论之后,我将其添加到WebRole标记下的servicedefinition.csdef中,以在提升的执行上下文中运行webrole,但是azure cmdlet仍未在脚本中运行:< / p>
<Runtime executionContext="elevated" />
更新:以下是调用脚本的C#代码
//create command
string path = HttpContext.Server.MapPath("/bin/InitializeResources.ps1");
PSCommand cmd = new PSCommand();
cmd.AddCommand(path);
cmd.AddParameter("websiteName", websiteName);
cmd.AddParameter("serverLogin", username);
cmd.AddParameter("serverPass", password);
cmd.AddParameter("location", location);
//set the command into a powershell object and invoke it
Runspace runspace = RunspaceFactory.CreateRunspace();
PowerShell ps = PowerShell.Create();
ps.Commands = cmd;
try
{
runspace.Open();
RunspaceInvoke runSpaceInvoker = new RunspaceInvoke(runspace);
runSpaceInvoker.Invoke("Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned -Force");
ps.Runspace = runspace;
Collection<PSObject> commandResults = ps.Invoke();
//save results
WebsiteInfo websiteInfo = new WebsiteInfo();
foreach (PSObject result in commandResults)
{
websiteInfo.Connectionstring = (string)result.Members["ConnectionString"].Value;
websiteInfo.WebsiteURL = (string)result.Members["WebsiteUrl"].Value;
websiteInfo.ftpUrl = (string)result.Members["SelfLink"].Value;
websiteInfo.ftpUrl = websiteInfo.ftpUrl.Substring(8);
int index = websiteInfo.ftpUrl.IndexOf(":");
if (index > 0)
websiteInfo.ftpUrl = websiteInfo.ftpUrl.Substring(0, index);
websiteInfo.ftpUrl = websiteInfo.ftpUrl.Replace("api", "ftp");
websiteInfo.publishUsername = (string)result.Members["Repository"].Value + "\\" + (string)result.Members["PublishUsername"].Value;
websiteInfo.publishPassword = (string)result.Members["PublishPassword"].Value;
}
runspace.Dispose();
runspace = null;
ps.Dispose();
ps = null;
}
答案 0 :(得分:0)
我遇到了类似的问题,你可以看到in this thread我在事件查看器中看不到任何异常,但是在每个shell调用后添加这些行我可以看到我的错误来自导入 - 模块线。
if (shell1.Streams.Error.Count > 0)
{
for (int i = 0; i < shell1.Streams.Error.Count; i++)
{
ResultBox.Text += "Error: " + shell1.Streams.Error[i] + "\r\n";
}
}
答案 1 :(得分:0)
当我们使用almamouz完成该项目时,由于安全考虑,无法通过Azure REST API生成资源,也无法通过webrole的PowerShell脚本执行此操作。 我们最终使用了web和worker角色,powershell脚本以worker角色运行。它包含所有敏感的服务器连接信息。