Abra remotamente um powershell remoto personalizado

1

Eu tenho 2 computadores. No computador A, eu tenho um módulo personalizado escrito em c # para o powershell 3.0 e instalado por meio de um MSI. Eu também tenho um atalho que abre powershell com o módulo já carregado.

Eu posso apenas clicar duas vezes no meu atalho e executar meu comando Do-Something neste computador sem nenhum problema, como o powershell do Exchange Server.

Mas agora eu gostaria de fazer isso de uma sessão remota no computador B em C #.

Então, minha pergunta é: como posso abrir uma sessão remota do powershell para o computador A com meu módulo já carregado e o shell configurado para que eu possa executar meu comando e obter o mesmo resultado do que se eu o executasse no computador? / p>     

por Yann Lebel 09.12.2012 / 05:39

1 resposta

2

Eu finalmente encontrei uma maneira de realizar o que eu precisava.

Primeiro, criei um script powershell para importar meu arquivo de script de módulo e módulo

ShellInitScript

function Get-ScriptDirectory
{
    $Invocation = (Get-Variable MyInvocation -Scope 1).Value
    Split-Path $Invocation.MyCommand.Path
}
$MyModuleDirectory = Get-ScriptDirectory
Set-Location $MyModuleDirectory 
Import-Module .\MyModule.psd1

MyModule.psd1

@{
GUID                = "[GENERATE A GUID HERE]" # Generate using $myGuid = [guid]::NewGuid() 

Author              = "Me"

CompanyName         = "My Company"

Copyright           = "© My Company. All rights reserved."

ModuleVersion       = "1.0.0.0"

ModuleToProcess     = "MyModule.psm1"
}

MyModule.psm1

Import-Module .\MyModuleCSharpAssembly.dll

function Enable-MyShellRemoting([switch]$Force)
{
    $proceed = 0

    if($Force -eq $false)
    {
        Write-Warning "Enable-MyShellRemoting restarts the WinRM service and all dependent services.'r'nAll WinRM sessions connected to Windows PowerShell session configurations are disconnected."

        $title = "Are you sure you want to perform this action?"
        $message = "Performing this operation will allow selected users to remotely run MyModule commands on this computer."

        $yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes"

        $no = New-Object System.Management.Automation.Host.ChoiceDescription "&No"

        $options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)

        $proceed = $Host.UI.PromptForChoice($title, $message, $options, 0) 
    }

    if($proceed -eq 0)
    {
        Enable-PSRemoting -Force

        if((Get-WmiObject Win32_ComputerSystem).PartOfDomain -eq $false){
            Set-Item WSMan:\localhost\Client\TrustedHosts *
            Restart-Service WinRM
        }

        $path = Join-Path -Path $MyModuleDirectory  -ChildPath "ShellInitScript.ps1"
        Register-PSSessionConfiguration -Name "MyShellUri" -StartupScript $path -Force
    }
}
function Disable-MyShellRemoting([switch]$Force, [switch]$DisablePSRemoting)
{
    $proceed = 0

    if($Force -eq $false)
    {
        Write-Warning "Disable-MyShellRemoting restarts the WinRM service and all dependent services.'r'nAll WinRM sessions connected to Windows PowerShell session configurations are disconnected."

        $title = "Are you sure you want to perform this action?"
        $message = "Performing this operation will prevent all users to remotely run MyModule commands on this computer.'r'nUse the the -DisablePSRemoting switch to disable all PowerShell remoting features."

        $yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes"

        $no = New-Object System.Management.Automation.Host.ChoiceDescription "&No"

        $options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)

        $proceed = $Host.UI.PromptForChoice($title, $message, $options, 0) 
    }

    if($proceed -eq 0)
    {
        if($DisablePSRemoting)
        {
            Disable-PSRemoting
        }

        if((Get-PSSessionConfiguration -Name "MyShellUri" -ErrorAction SilentlyContinue) -eq $null){
            Write-Host "The session configuration MyShellUri is already unregistered."
        }
        else {        
            Unregister-PSSessionConfiguration -Name "MyShellUri" -Force -ErrorAction Ignore
        }
    }
}

function Test-MyShellRemote()
{
    return "Test completed"
}

A dll MyModuleCSharpAssembly.dll é apenas um assembly .Net regular que contém Cmdlets personalizados.

A solução para o problema está na função Enable-MyShellRemoting, que permite habilitar o remoting do PowerShell e registrar uma configuração de sessão do Powershell personalizada com um script de estatística que carrega o módulo.

Em seguida, em C # tudo o que temos que fazer é especificar o ShellUri no objeto de conexão como este

WSManConnectionInfo connectionInfo = new WSManConnectionInfo();
connectionInfo.ComputerName = "MyComputer";
connectionInfo.ShellUri = "http://schemas.microsoft.com/powershell/MyShellUri";
using (Runspace remoteRunspace = RunspaceFactory.CreateRunspace(connectionInfo))
{
     remoteRunspace.Open();
     using (PowerShell shell = PowerShell.Create())
     {
          shell.Runspace = remoteRunspace;
          shell.AddCommand("Test-MyShellRemote");
          Collection<PSObject> results = shell.Invoke();
          //the results collection contains the string return by the command
     }
     remoteRunspace.Close();
 }
    
por 13.12.2012 / 00:14

Tags