Convert a small PS script into a long line in a .BATch file

前端 未结 3 1216
逝去的感伤
逝去的感伤 2020-11-27 23:06

I have this PowerShell code that I got from the answer to this question; it show the location/dimensions of the cmd.exe window where the PS code run:

$Window         


        
相关标签:
3条回答
  • 2020-11-27 23:35

    I would go for the -EncodedCommand option here. You simply Base64 encode the entire powershell script and then pass the Base64 string as an argument to powershell.exe:

    (assuming the script is here: C:\Path\To\Script.ps1)

    PS C:\> $ScriptText  = Get-Content C:\Path\To\Script.ps1 -Raw
    PS C:\> $ScriptBytes = [System.Text.Encoding]::Unicode.GetBytes($ScriptText)
    PS C:\> $EncCommand  = [System.Convert]::ToBase64String($ScriptBytes)
    

    $EncCommand now contains the Base64 encoded command, ready for use inside cmd.exe (or your batch file for that matter):

    C:\>powershell -EncodedCommand JABXAGkAbgBkAG8AdwBGAHUAbgBjAHQAaQBvAG4ALAAkAFIAZQBjAHQAYQBuAGcAbABlAFMAdAByAHUAYwB0ACAAPQAgAEEAZABkAC0AVAB5A
    HAAZQAgAC0ATQBlAG0AYgBlAHIARABlAGYAaQBuAGkAdABpAG8AbgAgAEAAJwANAAoAWwBEAGwAbABJAG0AcABvAHIAdAAoACIAdQBzAGUAcgAzADIALgBkAGwAbAAiACwAIABTAGUAd
    ABMAGEAcwB0AEUAcgByAG8AcgAgAD0AIAB0AHIAdQBlACkAXQANAAoAWwByAGUAdAB1AHIAbgA6ACAATQBhAHIAcwBoAGEAbABBAHMAKABVAG4AbQBhAG4AYQBnAGUAZABUAHkAcABlA
    C4AQgBvAG8AbAApAF0ADQAKAHAAdQBiAGwAaQBjACAAcwB0AGEAdABpAGMAIABlAHgAdABlAHIAbgAgAGIAbwBvAGwAIABHAGUAdABXAGkAbgBkAG8AdwBSAGUAYwB0ACgASQBuAHQAU
    AB0AHIAIABoAFcAbgBkACwAIAByAGUAZgAgAFIARQBDAFQAIABsAHAAUgBlAGMAdAApADsADQAKAFsAUwB0AHIAdQBjAHQATABhAHkAbwB1AHQAKABMAGEAeQBvAHUAdABLAGkAbgBkA
    C4AUwBlAHEAdQBlAG4AdABpAGEAbAApAF0ADQAKAHAAdQBiAGwAaQBjACAAcwB0AHIAdQBjAHQAIABSAEUAQwBUAA0ACgB7AA0ACgAgACAAIAAgAHAAdQBiAGwAaQBjACAAaQBuAHQAI
    ABMAGUAZgB0ADsADQAKACAAIAAgACAAcAB1AGIAbABpAGMAIABpAG4AdAAgAFQAbwBwADsADQAKACAAIAAgACAAcAB1AGIAbABpAGMAIABpAG4AdAAgAFIAaQBnAGgAdAA7AA0ACgAgA
    CAAIAAgAHAAdQBiAGwAaQBjACAAaQBuAHQAIABCAG8AdAB0AG8AbQA7AA0ACgB9AA0ACgAnAEAAIAAtAE4AYQBtAGUAIAAiAHQAeQBwAGUAJAAoAFsAZwB1AGkAZABdADoAOgBOAGUAd
    wBHAHUAaQBkACgAKQAgAC0AcgBlAHAAbABhAGMAZQAgACcALQAnACkAIgAgAC0AUABhAHMAcwBUAGgAcgB1AA0ACgANAAoAJABNAHkAVwBpAG4AZABvAHcASABhAG4AZABsAGUAIAA9A
    CAAKABHAGUAdAAtAFAAcgBvAGMAZQBzAHMAIAAtAEkAZAAgACgARwBlAHQALQBXAG0AaQBPAGIAagBlAGMAdAAgAFcAaQBuADMAMgBfAFAAcgBvAGMAZQBzAHMAIAAtAEYAaQBsAHQAZ
    QByACAAIgBQAHIAbwBjAGUAcwBzAEkAZAA9ACQAUABJAEQAIgApAC4AUABhAHIAZQBuAHQAUAByAG8AYwBlAHMAcwBJAGQAKQAuAE0AYQBpAG4AVwBpAG4AZABvAHcASABhAG4AZABsA
    GUADQAKAA0ACgAkAFcAaQBuAGQAbwB3AFIAZQBjAHQAIAA9ACAATgBlAHcALQBPAGIAagBlAGMAdAAgAC0AVAB5AHAAZQBOAGEAbQBlACAAJABSAGUAYwB0AGEAbgBnAGwAZQBTAHQAc
    gB1AGMAdAAuAEYAdQBsAGwATgBhAG0AZQANAAoAJABuAHUAbABsACAAPQAgACQAVwBpAG4AZABvAHcARgB1AG4AYwB0AGkAbwBuADoAOgBHAGUAdABXAGkAbgBkAG8AdwBSAGUAYwB0A
    CgAJABNAHkAVwBpAG4AZABvAHcASABhAG4AZABsAGUALABbAHIAZQBmAF0AJABXAGkAbgBkAG8AdwBSAGUAYwB0ACkADQAKAA0ACgBXAHIAaQB0AGUALQBIAG8AcwB0ACAAJABXAGkAb
    gBkAG8AdwBSAGUAYwB0AC4ATABlAGYAdAAgACQAVwBpAG4AZABvAHcAUgBlAGMAdAAuAFQAbwBwACAAJABXAGkAbgBkAG8AdwBSAGUAYwB0AC4AUgBpAGcAaAB0ACAAJABXAGkAbgBkA
    G8AdwBSAGUAYwB0AC4AQgBvAHQAdABvAG0A
    
    100 -2 1257 748
    
    0 讨论(0)
  • 2020-11-27 23:47

    Double quote literals must be escaped as \"

    @echo off
    
    PowerShell^
      $WindowFunction,$RectangleStruct = Add-Type -MemberDefinition '^
      [DllImport(\"user32.dll\", SetLastError = true)]^
      [return: MarshalAs(UnmanagedType.Bool)]^
      public static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);^
      [StructLayout(LayoutKind.Sequential)]^
      public struct RECT^
      {^
         public int Left;^
         public int Top;^
         public int Right;^
         public int Bottom;^
      }^
      ' -Name \"type$([guid]::NewGuid() -replace '-')\" -PassThru;^
      $MyWindowHandle = (Get-Process -Id (^
        Get-WmiObject Win32_Process -Filter \"ProcessId=$PID\"^
      ).ParentProcessId).MainWindowHandle;^
      $WindowRect = New-Object -TypeName $RectangleStruct.FullName;^
      $null = $WindowFunction::GetWindowRect($MyWindowHandle,[ref]$WindowRect);^
      Write-Host $WindowRect.Left $WindowRect.Top $WindowRect.Right $WindowRect.Bottom
    
    0 讨论(0)
  • 2020-11-27 23:49

    There was a topic on DosTips a while ago that addressed this. You can make a batch/Powershell hybrid with a simple header:

    <# :
    :: Header to create Batch/PowerShell hybrid
    @echo off
    setlocal
    set "POWERSHELL_BAT_ARGS=%*"
    if defined POWERSHELL_BAT_ARGS set "POWERSHELL_BAT_ARGS=%POWERSHELL_BAT_ARGS:"=\"%"
    endlocal & powershell -NoLogo -NoProfile -Command "$_ = $input; Invoke-Expression $( '$input = $_; $_ = \"\"; $args = @( &{ $args } %POWERSHELL_BAT_ARGS% );' + [String]::Join( [char]10, $( Get-Content \"%~f0\" ) ) )"
    
    :: Any batch code that gets run after your PowerShell goes here
    goto :EOF
    #>
    

    Just throw your Powershell code after the #> and save the file as a regular .bat script. In your case:

    <# :
    :: Header to create Batch/PowerShell hybrid
    @echo off
    setlocal
    set "POWERSHELL_BAT_ARGS=%*"
    if defined POWERSHELL_BAT_ARGS set "POWERSHELL_BAT_ARGS=%POWERSHELL_BAT_ARGS:"=\"%"
    endlocal & powershell -NoLogo -NoProfile -Command "$_ = $input; Invoke-Expression $( '$input = $_; $_ = \"\"; $args = @( &{ $args } %POWERSHELL_BAT_ARGS% );' + [String]::Join( [char]10, $( Get-Content \"%~f0\" ) ) )"
    goto :EOF
    #>
    
    $WindowFunction,$RectangleStruct = Add-Type -MemberDefinition @'
    [DllImport("user32.dll", SetLastError = true)]
    [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool GetWindowRect(IntPtr hWnd, ref RECT lpRect);
    [StructLayout(LayoutKind.Sequential)]
    public struct RECT
    {
        public int Left;
        public int Top;
        public int Right;
        public int Bottom;
    }
    '@ -Name "type$([guid]::NewGuid() -replace '-')" -PassThru
    
    $MyWindowHandle = (Get-Process -Id (Get-WmiObject Win32_Process -Filter "ProcessId=$PID").ParentProcessId).MainWindowHandle
    
    $WindowRect = New-Object -TypeName $RectangleStruct.FullName
    $null = $WindowFunction::GetWindowRect($MyWindowHandle,[ref]$WindowRect)
    
    Write-Host $WindowRect.Left $WindowRect.Top $WindowRect.Right $WindowRect.Bottom
    
    0 讨论(0)
提交回复
热议问题