0

I have a script, below, which I have in a Scripts folder. It references a set of command prompt applications $cmd1.exe, etc.. Using either Powershell or the Integrated Powershell terminal in VS Code, I follow these steps to use it:

  1. Dot source the script from the Scripts directory > .\new-customconfig.ps1,
  2. Change to the working directory > cd [New Directory],
  3. Use the function in the script and pass a filename from the working directory > New-CustomConfig .\FileName.

It passes the file from the working directory the first time I run the script, but from any subsequent runs, it looks for the file in the Scripts directory.

Is there something I am doing wrong?

Function New-CustomConfig {
    [CmdletBinding()]
    Param(
        [Parameter(Mandatory=$true)]
        [string]
        $FileName
    )

    Begin {
        #Set tools directory
        $ToolD = '[Directory]\Tools'

        #Clean up filename
        $FileName = $FileName -replace '^[\W]*', ''

        #Setup Executables
        $cmdtools = "\cmd1.exe", "\cmd2.exe", "\cmd3.exe"

        #Setup Arguments
        $cmdargs = "cmd1args", "cmd2args", "cmd3args"

        #Setup Write-Host Comments
        $cmdecho = "echo1", "echo2", "echo3"

        #Setup command object info
        $cmdinfo = New-Object System.Diagnostics.ProcessStartInfo
        $cmdinfo.RedirectStandardError = $true
        $cmdinfo.RedirectStandardOutput = $true
        $cmdinfo.UseShellExecute = $false

        #Create command object
        $cmd = New-Object System.Diagnostics.Process

        "Generating Config for $FileName"
    }

    Process {
        for ($i = 0; $i -le $cmdtools.Count; $i++) {
            $cmdinfo.FileName = $ToolD + $cmdtools[$i]
            $cmdinfo.Arguments = '' + $cmdargs[$i] + ''
            Write-Host $i
            Write-Host $cmdinfo.FileName
            Write-Host $cmdinfo.Arguments
            Write-Host $(Get-Location)

            $cmdecho[$i]

            $cmd.StartInfo = $cmdinfo
            $cmd.Start() | Out-Null
            $cmd.WaitForExit()

            $stdout = $cmd.StandardOutput.ReadToEnd()
            $stderr = $cmd.StandardError.ReadToEnd()

            Write-Host "stdout: $stdout"
            Write-Host "stderr: $stderr"
            Write-Host "exit code: " + $p.ExitCode
        }
    }

    End {
        "Press any key to continue..."
        $null = $host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown')
    }

}
phuclv
  • 37,963
  • 15
  • 156
  • 475
Eeshwar
  • 53
  • 6
  • 1
    PowerShell's current location is not the same thing as process' working directory. And `cd` only change current location but not working directory. Also `$stdout = $cmd.StandardOutput.ReadToEnd(); $stderr = $cmd.StandardError.ReadToEnd()` is asking for deadlock. – user4003407 Aug 22 '18 at 10:05
  • Thanks! I resolved it by setting the `$cmdinfo.WorkingDirectory` property to `$(Get-Location)`. For the potential deadlock, I resolved it by using a string builder to asynchronously read stdout and stderr: `$stdOutBld = New-Object -TypeName System.Text.StringBuilder` `$eventChk = { if(! [String]::IsNullOrEmpty($EventArgs.Data)) { $Event.MessageData.AppendLine($EventArgs.Data)` `$stdOutEvt = Register-ObjectEvent -InputObject $cmd -Action $eventChk -EventName 'OutputDataReceived' -MessageData $stdOutBld` `$cmd.BeginOutputReadLine()` – Eeshwar Aug 31 '18 at 01:47

0 Answers0