使用参数在构建后调用 powershell 脚本

发布于 2024-10-17 09:58:35 字数 1147 浏览 6 评论 0原文

我试图让 Powershell 在构建后运行我的 PS 脚本 - 但不知怎的,它并没有像预期的那样工作:

构建后中的以下命令:

C:\WINDOWS\system32\windowspowershell\1.0\powershell.exe
  -Command "& $(MSBuildProjectDirectory)\CreateSite.ps1 'auto'"

(为了更好的阅读而插入换行符)

该命令成功执行了 powershell 脚本,但它无法运行(Build 的输出)中的命令: 运行构建后命令:

Add-PSSnapin : No snap-ins have been registered for Windows PowerShell version 2
At C:\path\CreateSite.ps1:4 char:
38
+ Add-PsSnapin <<<< Microsoft.SharePoint.PowerShell}
+ CategoryInfo : InvalidArgument: (Microsoft.SharePoint.PowerShell:String) [Add-PSSnapin], PSArgumentException
+ FullyQualifiedErrorId : AddPSSnapInRead,Microsoft.PowerShell.Commands.AddPSSnapinCommand

接下来会出现许多错误,因为所有后续命令都需要 Sharepoint 管理单元。

  • 从 cmd 运行 powershell C:\path\CreateSite.ps1 auto 时 - 一切正常。
  • 打开 powershell.exe 并运行 C:\path\CreateSite.ps1 auto 时 - 一切正常。
  • 右键单击 CreateSite.ps1 -->使用 powershell 运行 - 一切正常。

脚本中的相关行就是 Add-PsSnapin Microsoft.SharePoint.PowerShell

如何运行该脚本(并让它包含 PSSnapIn)并在 Visual Studio 构建后向其传递参数?

I'm trying to get Powershell to run my PS script in post built - but somehow it doesn't work like it's supposed to:

Following command in Post-Build:

C:\WINDOWS\system32\windowspowershell\1.0\powershell.exe
  -Command "& $(MSBuildProjectDirectory)\CreateSite.ps1 'auto'"

(inserted line break for better reading)

The command executes the powershell script sucessfully, but what it can't do is run the commands within (Output from Build):
Rund Post-Build Command:

Add-PSSnapin : No snap-ins have been registered for Windows PowerShell version 2
At C:\path\CreateSite.ps1:4 char:
38
+ Add-PsSnapin <<<< Microsoft.SharePoint.PowerShell}
+ CategoryInfo : InvalidArgument: (Microsoft.SharePoint.PowerShell:String) [Add-PSSnapin], PSArgumentException
+ FullyQualifiedErrorId : AddPSSnapInRead,Microsoft.PowerShell.Commands.AddPSSnapinCommand

And following that are many errors because all subsequent commands need the Sharepoint Snap-In.

  • When running powershell C:\path\CreateSite.ps1 auto from cmd - everything works.
  • When opening powershell.exe and running C:\path\CreateSite.ps1 auto - everything works.
  • When right clicking CreateSite.ps1 --> run with powershell - everything works.

The relevant line in the script is simply Add-PsSnapin Microsoft.SharePoint.PowerShell.

How can I just run the darn script (and get it to include the PSSnapIn) passing it a parameter in Visual Studio post-build?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

萌化 2024-10-24 09:58:35

(这个线程并不新鲜,但我从 Google 来到这里,所以我认为分享我发现的解决方案对其他人来说会很有趣)

我尝试将 powershell.exe 的路径更改为“%WINDIR%\SysNative\WindowsPowerShell\v1.0 ” \powershell.exe”并且运行完美。从构建后事件调用 64 位版本,并成功添加 SharePoint 管理单元。

本文来源:http://msdn.microsoft.com/en-us/ Library/ff798298.aspx,“在 Visual Studio 中使用 Windows PowerShell 脚本自动执行任务”。

(This thread is not new, but I got here from Google, so I thought sharing the solution I found would be interesting to others)

I tried changing the path to powershell.exe to "%WINDIR%\SysNative\WindowsPowerShell\v1.0\powershell.exe" and it worked perfect. The 64 bits version is called from the Post Build event and it successfully adds the SharePoint snapin.

Credits to this article: http://msdn.microsoft.com/en-us/library/ff798298.aspx, "Using Windows PowerShell Scripts to Automate Tasks in Visual Studio".

撩发小公举 2024-10-24 09:58:35

由于文件系统虚拟化,您无法真正从 32 位进程(即 Visual Studio - 托管 msbuild 引擎)指定 64 位版本的 PowerShell 的路径。解决此问题的一种黑客方法是创建一个以 64 位运行的 64 位启动器,并将启动 64 位版本的 PowerShell。下面是一个简单的 C# 程序,可以执行此操作:

using System;
using System.Diagnostics;

class App
{
  static int Main(string[] args)
  {
    Process process = Process.Start("PowerShell.exe", String.Join(" ", args));
    process.WaitForExit();
    return process.ExitCode;
  }
}

确保将其编译为 64 位,如下所示:

csc .\PowerShell64.cs /platform:x64

然后,从构建后事件执行此启动程序 exe,并向其传递您想要调用 64 位 PowerShell 的参数。另外,对于 PowerShell 2.0,我建议使用 File 参数来执行脚本,例如:

c:\path\PowerShell64.exe -File "$(MSBuildProjectDirectory)\CreateSite.ps1" auto

也就是说,肯定必须有其他方法(实用程序)从 64 位进程启动 exe。

Because of file system virtualization, you can't really specify the path to the 64-bit version of PowerShell from a 32-bit process (ie Visual Studio - which hosts the msbuild engine). One hack-ish way to work around this is to create a 64-bit launcher that runs as 64-bit and will launch the 64-bit version of PowerShell. Here's a simple C# program that will do this:

using System;
using System.Diagnostics;

class App
{
  static int Main(string[] args)
  {
    Process process = Process.Start("PowerShell.exe", String.Join(" ", args));
    process.WaitForExit();
    return process.ExitCode;
  }
}

Be sure to compile this as 64-bit like so:

csc .\PowerShell64.cs /platform:x64

Then, from your post-build event execute this launcher exe passing it the parameters you want to invoke 64-bit PowerShell with. Also, with PowerShell 2.0 I would recommend using the File parameter to execute a script e.g.:

c:\path\PowerShell64.exe -File "$(MSBuildProjectDirectory)\CreateSite.ps1" auto

That said, surely there has to be some other way (utility) that launches exes from a 64-bit process.

我一直都在从未离去 2024-10-24 09:58:35

当您直接运行脚本时,您可能使用 32 位 PowerShell,而在 msbuild 脚本中使用 64 位,反之亦然。另请查看 错误消息:“没有为 Windows PowerShell 版本 2 注册任何管理单元。”

When you run you script directly, you probably use 32bit PowerShell and in your msbuild script 64bit or vice versa. Also have a look at Error msg: “No snap-ins have been registered for Windows PowerShell version 2.”.

马蹄踏│碎落叶 2024-10-24 09:58:35

输出重定向的一个稍微好一点的变体:

using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;

namespace ConsoleApplication1
{
    class App
    {
        static int Main(string[] args)
        {
            Console.WriteLine("sh64 args: " + string.Join(", ", args));
            var start = new ProcessStartInfo
                {
                    FileName = args.First(),
                    Arguments = string.Join(" ", args.Skip(1).ToArray()),
                    UseShellExecute = false,
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    RedirectStandardInput = false,
                    CreateNoWindow = true
                };

            using (var process = Process.Start(start))
            {
                while (!process.HasExited)
                {
                    using (var reader = process.StandardOutput)
                        Drain(reader, false);
                    using (var reader = process.StandardError)
                        Drain(reader, true);
                }
                process.WaitForExit();
                return process.ExitCode;
            }
        }

        static void Drain(TextReader reader, bool error)
        {
            ColourizeError(error, () =>
                {
                    var buf = new char[256];
                    int read;
                    while ((read = reader.Read(buf, 0, buf.Length)) != 0)
                        Console.Write(new string(buf, 0, read));
                });
        }

        static void ColourizeError(bool error, Action a)
        {
            var prev = Console.ForegroundColor;
            Console.ForegroundColor = error ? ConsoleColor.Red : ConsoleColor.White;
            var mre = new ManualResetEventSlim(false);
            try
            {
                a();
            }
            finally
            {
                Console.ForegroundColor = prev;
                mre.Set(); // runs on GC thread on servers and is reentrant/interleaved concurrency in workstations!
            }
            mre.Wait();
        }
    }
}

使用 sh64 powershell -File ./buildscripts/deploy.ps1 -Ex RemoteSigned 进行调用

A slightly better variant of the output redirection:

using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;

namespace ConsoleApplication1
{
    class App
    {
        static int Main(string[] args)
        {
            Console.WriteLine("sh64 args: " + string.Join(", ", args));
            var start = new ProcessStartInfo
                {
                    FileName = args.First(),
                    Arguments = string.Join(" ", args.Skip(1).ToArray()),
                    UseShellExecute = false,
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    RedirectStandardInput = false,
                    CreateNoWindow = true
                };

            using (var process = Process.Start(start))
            {
                while (!process.HasExited)
                {
                    using (var reader = process.StandardOutput)
                        Drain(reader, false);
                    using (var reader = process.StandardError)
                        Drain(reader, true);
                }
                process.WaitForExit();
                return process.ExitCode;
            }
        }

        static void Drain(TextReader reader, bool error)
        {
            ColourizeError(error, () =>
                {
                    var buf = new char[256];
                    int read;
                    while ((read = reader.Read(buf, 0, buf.Length)) != 0)
                        Console.Write(new string(buf, 0, read));
                });
        }

        static void ColourizeError(bool error, Action a)
        {
            var prev = Console.ForegroundColor;
            Console.ForegroundColor = error ? ConsoleColor.Red : ConsoleColor.White;
            var mre = new ManualResetEventSlim(false);
            try
            {
                a();
            }
            finally
            {
                Console.ForegroundColor = prev;
                mre.Set(); // runs on GC thread on servers and is reentrant/interleaved concurrency in workstations!
            }
            mre.Wait();
        }
    }
}

Call with sh64 powershell -File ./buildscripts/deploy.ps1 -Ex RemoteSigned

皇甫轩 2024-10-24 09:58:35

添加包含以下内容的 cmd 文件(例如 run-script.cmd):

    @echo off
    set pspath=%windir%\Sysnative\WindowsPowerShell\v1.0
    if not exist %pspath%\powershell.exe set pspath=%windir%\System32\WindowsPowerShell\v1.0
    %pspath%\powershell.exe -ExecutionPolicy RemoteSigned %*

并以这种方式从构建事件中调用它:

    $(SolutionDir)scripts\run-script.cmd $(SolutionDir)scripts\restore-default-file.ps1 -source $(ProjectDir)App_Data\Configs\Mip.Security.Sample.config -destination $(ProjectDir)App_Data\Configs\Mip.Security.config

add cmd-file (e.g. run-script.cmd) with this content:

    @echo off
    set pspath=%windir%\Sysnative\WindowsPowerShell\v1.0
    if not exist %pspath%\powershell.exe set pspath=%windir%\System32\WindowsPowerShell\v1.0
    %pspath%\powershell.exe -ExecutionPolicy RemoteSigned %*

and call it from build event in a such manner:

    $(SolutionDir)scripts\run-script.cmd $(SolutionDir)scripts\restore-default-file.ps1 -source $(ProjectDir)App_Data\Configs\Mip.Security.Sample.config -destination $(ProjectDir)App_Data\Configs\Mip.Security.config

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文