7

Estoy intentando conseguir PowerShell para ejecutar mi script PS en postas - pero de alguna manera no funciona como se supone a:de llamadas en la post-construida con parámetros

siguiente comando en Post-Construcción :

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

(salto de línea insertada para una mejor lectura)

el comando se ejecuta la secuencia de comandos PowerShell con éxito, pero lo que no puede hacer es ejecutar los comandos dentro (la salida de la Estructura): Rund posterior a la generación de comandos:

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 

y después de que son muchos errores porque todos los comandos posteriores necesitan el Sharepoint complemento.

  • Al ejecutar powershell C: \ path \ CreateSite.ps1 auto desde cmd, todo funciona.
  • Al abrir powershell.exe y ejecutar C: \ path \ CreateSite.ps1 auto - todo funciona.
  • Al hacer clic derecho en CreateSite.ps1 -> ejecutar con powershell - todo funciona.

La línea relevante en el script es simplemente Add-PsSnapin Microsoft.SharePoint.PowerShell.

¿Cómo puedo ejecutar el script de darn (y hacer que incluya el PSSnapIn) pasando un parámetro en Visual Studio post-build?

Respuesta

6

Debido a la virtualización del sistema de archivos, no se puede especificar realmente la ruta a la versión de 64 bits de PowerShell desde un proceso de 32 bits (es decir, Visual Studio - que aloja el motor msbuild). Una forma de solucionar esto es crear un iniciador de 64 bits que se ejecute como de 64 bits y que inicie la versión de 64 bits de PowerShell. Aquí está un simple C# programa que va a hacer esto:

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; 
    } 
} 

Asegúrese de compilar esto como de 64 bits, así:

csc .\PowerShell64.cs /platform:x64 

Luego, a partir de su evento posterior a la generación ejecutar este exe lanzador pasándolo los parámetros con los que desea invocar PowerShell de 64 bits. Además, con PowerShell 2.0 Yo recomiendo usar el parámetro File para ejecutar un script ej .:

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

Dicho esto, sin duda, tiene que haber alguna otra manera (utilidad) que lanza exes de un proceso de 64 bits.

+0

Esto, señor, es ** muy ** interesante y funciona sin problemas! (sin embargo, no es necesario usar csc.exe; basta con establecer la plataforma de destino en x64) –

1

Cuando ejecuta directamente la secuencia de comandos, probablemente utilice 32 bits de PowerShell y en su script de msbuild de 64 bits o viceversa. También eche un vistazo a Error msg: “No snap-ins have been registered for Windows PowerShell version 2.”.

+0

Sí, el complemento de SharePoint es 64bit. +1 – x0n

+1

Está ejecutando el PowerShell de 64 bits (que sería el predeterminado en un sistema operativo de 64 bits). – JasonMArcher

+0

He leído sobre la controversia de 64 bits/32 bits, es por eso que estoy usando la ruta directa C: \ windows \ system32 \ ... a la versión de 64 bits de powershell en lugar de la ruta SysWOW64 que conduce a la 32bit PowerShell. ¿Podría tener algo que ver con el edificio del proyecto con "Cualquier CPU" en lugar de x64? –

1

Un poco mejor variante de la redirección de la salida:

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(); 
     } 
    } 
} 

llamada con sh64 powershell -File ./buildscripts/deploy.ps1 -Ex RemoteSigned

+0

¿Estás seguro de que deseas publicar aquí? esta pregunta se trataba de ejecutar Powershell en 64 bits en lugar de 32 bits. ¿Cómo se puede redireccionar desde allí? –

+0

Porque uno tendría el problema de la pregunta si uno está tratando de crear un entorno de CI. En un entorno de CI, debemos ser capaces de obtener el resultado de PS como parte de la compilación. Por lo tanto, necesitamos la solución de este hilo así como la redirección de salida. – Henrik

+0

Muy bien. Eso es verdad sobre CI. Aún así, creo que no está relacionado con esta pregunta y la gente probablemente no encontrará tu respuesta ;-) –

16

(Este hilo no es nuevo, pero tengo aquí desde Google, así que pensé compartir la solución que encontré lo haría ser interesante para los demás)

Intenté cambiar la ruta de acceso a powershell.exe a "% WINDIR% \ SysNative \ WindowsPowerShell \ v1.0 \ powershell.exe" y funcionó perfectamente. La versión de 64 bits se llama desde el evento Post Build y agrega correctamente el snapin de SharePoint.

Créditos a este artículo: http://msdn.microsoft.com/en-us/library/ff798298.aspx, "Uso de scripts de Windows PowerShell para automatizar tareas en Visual Studio".

+2

+1 para una solución muy elegante y realmente correcta! Thx para compartir. –

+1

Mi esclavo Jenkins se negó a ejecutar Powershell en un proceso de 64 bits por todos los demás medios que he probado, ¡pero su solución funciona! –

+0

genial, gracias! –

1

añadir cmd en archivos (por ejemplo, gestión script.cmd) con este contenido:

 

    @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 %* 

y llamarlo desde el evento en una acumulación tal manera:

 

    $(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 

Cuestiones relacionadas