Auro Sarma
Auro Sarma

Reputation: 441

Unable to execute PowerShell script from batch file to run in CMD mode

I created a PowerShell script for FileWatcher. I need to execute it in C#. I tried in many ways but it didn't work. I even created a batch file to execute my script. still it is not working, simply the console gets opened and closed. but when i run each step manually in the command prompt I could able to execute the script.

Below is my PowerShell script:

$folder = 'D:\'
$filter = '*.csv'
$fsw = New-Object IO.FileSystemWatcher $folder, $filter -Property @{
    IncludeSubdirectories = $false;
    NotifyFilter = [IO.NotifyFilters]'FileName, LastWrite'
}
Register-ObjectEvent $fsw Changed -SourceIdentifier FileChanged -Action {
    $name = $Event.SourceEventArgs.Name
    $changeType = $Event.SourceEventArgs.ChangeType
    $timeStamp = $Event.TimeGenerated
    Write-Host "The file '$name' was $changeType at $timeStamp" -Fore red
    Out-File -FilePath D:\outp.txt -Append -InputObject "The file '$name' was $changeType at $timeStamp"
}

Here is the batch file

D:
powershell.exe
powershell Set-ExecutionPolicy RemoteSigned
./FileWatcherScript

Upvotes: 0

Views: 1276

Answers (1)

Micah R Ledbetter
Micah R Ledbetter

Reputation: 1088

To call a script from Powershell, you should use the -File argument. I'd change your batch file to look something like this - all you need is this one line:

powershell.exe -ExecutionPolicy RemoteSigned -File D:\FileWatcherScript.ps1

Starting powershell.exe without passing any arguments, as in the batch script in your post, will always start an interactive shell that must be exited manually. To run commands through Powershell programatically and exit when finished, you can pass the -File argument as I did above, or the -Command argument which takes a string or script block. Here is a short example of the -Command argument taking a string:

powershell.exe -Command "Invoke-RestMethod https://example.com/api/do/thing; Invoke-RestMethod https://example.com/api/stop/otherthing"

That invocation calls Invoke-RestMethod twice on two different URLs, and demonstrates that you can separate commands with a semicolon (;) to run one after another.

You can also pass a scriptblock to -Command, but note that this only works from within another Powershell session. That looks like this:

powershell.exe -Command { Invoke-RestMethod https://example.com/api/do/thing; Invoke-RestMethod https://example.com/api/stop/otherthing }

That invocation does the same thing as the previous one. The difference is that it is using a scriptblock - a Powershell construct, which again only works if the parent shell is also Powershell - and it's a bit nicer since you have fewer string quoting problems.

Upvotes: 0

Related Questions