我有一个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网站,但在发布和从 Cloud 服务运行时抛出和退出 .
当然我搜索了一个解决方案,我发现我必须将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功能?有替代解决方案吗?
Update: 在Gaurav的评论之后,我将其添加到WebRole标记下的servicedefinition.csdef中,以在提升的执行上下文中运行webrole,但是azure cmdlet仍未在脚本中运行:
<Runtime executionContext="elevated" />
Update: 这是调用脚本的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;
}
2 回答
当我们使用almamouz完成该项目时,由于安全考虑,无法通过Azure REST API生成资源,也无法通过来自webrole的PowerShell脚本执行此操作 . 我们最终使用了web和worker角色,powershell脚本以worker角色运行 . 它包含所有敏感的服务器连接信息 .
我遇到了类似的问题,你可以看到in this thread我在事件查看器中看不到任何异常,但是在每个shell调用后添加这些行我可以看到我的错误出现在Import-Module行中 .