0

I want to run the following Powershell command by executing a .bat file:

Add-Type -TypeDefinition @'
using System.Runtime.InteropServices;
[Guid("5CDF2C82-841E-4546-9722-0CF74078229A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IAudioEndpointVolume
{
    // f(), g(), ... are unused COM method slots. Define these if you care
    int f(); int g(); int h(); int i();
    int SetMasterVolumeLevelScalar(float fLevel, System.Guid pguidEventContext);
    int j();
    int GetMasterVolumeLevelScalar(out float pfLevel);
    int k(); int l(); int m(); int n();
    int SetMute([MarshalAs(UnmanagedType.Bool)] bool bMute, System.Guid pguidEventContext);
    int GetMute(out bool pbMute);
}
[Guid("D666063F-1587-4E43-81F1-B948E807363F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IMMDevice
{
    int Activate(ref System.Guid id, int clsCtx, int activationParams, out IAudioEndpointVolume aev);
}
[Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IMMDeviceEnumerator
{
    int f(); // Unused
    int GetDefaultAudioEndpoint(int dataFlow, int role, out IMMDevice endpoint);
}
[ComImport, Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")] class MMDeviceEnumeratorComObject { }
public class Audio
{
    static IAudioEndpointVolume Vol()
    {
        var enumerator = new MMDeviceEnumeratorComObject() as IMMDeviceEnumerator;
        IMMDevice dev = null;
        Marshal.ThrowExceptionForHR(enumerator.GetDefaultAudioEndpoint(/*eRender*/ 0, /*eMultimedia*/ 1, out dev));
        IAudioEndpointVolume epv = null;
        var epvid = typeof(IAudioEndpointVolume).GUID;
        Marshal.ThrowExceptionForHR(dev.Activate(ref epvid, /*CLSCTX_ALL*/ 23, 0, out epv));
        return epv;
    }
    public static float Volume
    {
        get { float v = -1; Marshal.ThrowExceptionForHR(Vol().GetMasterVolumeLevelScalar(out v)); return v; }
        set { Marshal.ThrowExceptionForHR(Vol().SetMasterVolumeLevelScalar(value, System.Guid.Empty)); }
    }
    public static bool Mute
    {
        get { bool mute; Marshal.ThrowExceptionForHR(Vol().GetMute(out mute)); return mute; }
        set { Marshal.ThrowExceptionForHR(Vol().SetMute(value, System.Guid.Empty)); }
    }
}
'@
[audio]::Volume  = 1

The problem with cmd command prompt is that it interprets a new line of code as execute this command.

However, when I enter everything into a PowerShell command line, it does not do so.

Is there any possibility to run this whole PowerShell script by executing a batch script?

I have already tried powershell -command "and the whole script", but that did not work either... cmd keeps thinking a new line means to execute it.

sɐunıɔןɐqɐp
  • 3,332
  • 15
  • 36
  • 40
9a2on
  • 1
  • 2
  • That doesnt work, I get an error saying that after a "here-string-header" or after the end of a line youre not allowed to set characters – 9a2on Jul 02 '18 at 10:22

2 Answers2

0

Try this if you want to execute your PS1 File:

powershell.exe -executionpolicy bypass -file "YOUR_FILE_NAME.ps1"

If you want to do everythin in one batch File do this:

powershell.exe
"Your Command"

You just need to put your command into the next line.

J. Doe
  • 43
  • 5
  • okay, but what does the ps1 file have to contain? its a script, right? so I literally need a whole new command. – 9a2on Jul 02 '18 at 10:31
  • I edited my answer – J. Doe Jul 02 '18 at 10:34
  • that doesnt work. My command is not just one line long. If I do powershell.exe "my whole command with several lines" it just ignores everything after powershell.exe – 9a2on Jul 02 '18 at 10:38
0

First of all, if you have a long PowerShell command, the maximum limit of characters per cmd command line can be easily reached (I believe it is ~8191 characters?).

Furthermore, it is quite uncommon to execute such big PowerShell commands directly in the cmd command line. Usually you should put it inside a file ending with .ps1, and then you execute it using the following command:

powershell.exe -executionpolicy bypass -file script.ps1

In case you really need to run the PowerShell command as you mentioned, you must first modify it a little bit. Take as example the following PS script:

function Say-Hello
{
   [CmdletBinding()]
   Param
   (
       [string] $name
   )
   Process
   {
        # Let's say hello!
        $str = "Hello " + $name
        Write-Output $str
   }
}
Say-Hello "Jason"


The trick is to replace all \r\n line endings with \n, using a text editor (like Notepad++ for instance):

enter image description here


HOWEVER, you must first add some ; at the end of many of your PowerShell commands, because that is the only way you can tell PowerShell that a new PowerShell command is being issued. Otherwise, PowerShell may take 2 lines of your code and execute them as a single one, since they look all concatenated after you removed the newlines.

Then remove all line comments from your code, and escape all double quotes (or alternatively, just replace them with single quotes):

function Say-Hello
{
   [CmdletBinding()]
   Param
   (
       [string] $name
   )
   Process
   {
        $str = 'Hello ' + $name;
        Write-Output $str
   }
}
Say-Hello 'Jason'


Now you are ready to copy it from your text editor tool (Notepad++ in my case) and paste it to your command line like this:

powershell.exe -executionpolicy bypass -command "function Say-Hello { [CmdletBinding()] Param ([string] $name) Process { $str = 'Hello ' + $name; Write-Output $str }} Say-Hello 'Jason'"

And the expected output for that is:

Hello Jason

sɐunıɔןɐqɐp
  • 3,332
  • 15
  • 36
  • 40
  • _"it is quite uncommon to execute such big PowerShell commands directly in the `cmd` command line"_. I use large segments of PowerShell code embedded in Batch files all the time. You may review a general method to do so at [this thread](https://www.dostips.com/forum/viewtopic.php?f=3&t=6936) and there are a lot of examples, like [Tetris game](https://www.dostips.com/forum/viewtopic.php?f=3&t=6936#p46206), [Spiral in color](https://www.dostips.com/forum/viewtopic.php?f=3&t=4896&p=49821#p49821), [2048 game](https://www.dostips.com/forum/viewtopic.php?f=3&t=6936#p46413), and a long et cetera... – Aacini Jul 02 '18 at 19:52
  • @Aacini: Thanks for the info, I didn't know it was so common to develop games in PowerShell + batch files. – sɐunıɔןɐqɐp Jul 02 '18 at 21:00