Set-ExecutionPolicy Unrestricted
我有一个 VS 2012 MVC 4 Web 角色项目,并且在从启动 cmd运行后,我成功地从角色的 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,将 Azure Powershell 从 webpicmd 安装到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 发表评论后,我将其添加到我的 servicedefinition.csdef 中的 WebRole 标记下,以在提升的执行上下文中运行 webrole,但 azure cmdlet 仍未在脚本中运行:
<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;
}