Get Batch Script Name (Parant Process) from ps1 script

Welcome Forums General PowerShell Q&A Get Batch Script Name (Parant Process) from ps1 script

Viewing 15 reply threads
  • Author
    Posts
    • #283963
      Participant
      Topics: 2
      Replies: 8
      Points: 39
      Rank: Member

      Hi Folks –

      I have a batch script where I call a .ps1 script.  Rather than pass the batch script name as a parameter to the ps1 (which is easy enough to do), I was wondering if there is an easy to way to extract the batch script name within the ps1 script itself?

      I call the ps1 as follows:

      POWERSHELL -ExecutionPolicy ByPass -file "%EMAIL_BIN%Email_Utility.ps1" ^
      "%EMAIL_SERVER%" ^
      "%EMAIL_FROM%" ^
      "%EMAIL_TO%" ^
      "%EMAIL_PSSWD%" ^
      "%EMAIL_PORT%" && (
      ECHO Success : Email Sent Successfully
      ) || (
      ECHO Warning : Email Failed
      ECHO.
      TYPE "emailerror"
      )

      Thank you!

      • This topic was modified 2 weeks, 1 day ago by simms740063.
    • #283999
      Participant
      Topics: 5
      Replies: 252
      Points: 999
      Helping Hand
      Rank: Major Contributor

      The problem is the parent process would probably be cmd.exe.  You can use win32_process CIM to get to the parent process then access any properties you need (commandline property should point you to the executable).  Also the automatic variable $PID will have the processID of the current instance of PowerShell.  Here is an example:

       

    • #284008
      Participant
      Topics: 2
      Replies: 8
      Points: 39
      Rank: Member

      THank you! Can’t seem to derive the batch script name thought from the PID.

    • #284011
      Participant
      Topics: 2
      Replies: 8
      Points: 39
      Rank: Member

      So I am getting closer.  This code retrieves the full path and script name.  However I need to parse the output between the ” symbols and then get the string AFTER the last \ symbol.

      Is that possible?

      $ParentProc = gwmi Win32_Process | ? { $_.commandline -match ".cmd" } | ft commandline,processid -auto

    • #284029
      Participant
      Topics: 5
      Replies: 252
      Points: 999
      Helping Hand
      Rank: Major Contributor

      You can certainly parse a string in PowerShell however you want.  I would use the -replace operator which uses regex to find the section of string you are looking for.  I’m assuming in your case that the batch file is an argument to the .cmd  If so -replace may look something like this:

      Also you may not want to assume there is only one process running who’s commandline matches the regular expression “.cmd”.  I would find the actual parent process using the $PID variable like I did in my previous example.  Since “.cmd” is a regular expression (-match operator) the “.” means match any character.  If you want the literal “.” you would need to escape it “\.”

      Recommend review Get-Help about_Comparison_Operators and Get-Help about_Regular_Expressions

    • #284134
      Participant
      Topics: 2
      Replies: 8
      Points: 39
      Rank: Member

      Hi –

      I’m calling a ps1 within a batch file as such:

      POWERSHELL -ExecutionPolicy ByPass -file “%EMAIL_BIN%Email_Utility.ps1” ^
      “%EMAIL_SERVER%” ^
      “%EMAIL_FROM%” ^
      “%EMAIL_TO%” ^
      “%EMAIL_PSSWD%” ^
      “%EMAIL_PORT%”

      I use that code in many batch scripts, therefore I from the ps1 I want to be able to determine the name of the batch script it has been called from.  I don’t understand your examples based on my need…

      I can very easily add a new parameter from the batch file and pass the batch file name to ps1, but I have hundreds of batches I’d need to update.  Hence, I’ trying to do this logic int he ps1 since I use the same ps1 file across all batch scripts…

      • This reply was modified 2 weeks, 1 day ago by simms740063.
      • This reply was modified 2 weeks, 1 day ago by simms740063.
      • This reply was modified 2 weeks, 1 day ago by simms740063.
    • #284248
      Participant
      Topics: 5
      Replies: 252
      Points: 999
      Helping Hand
      Rank: Major Contributor

      Did you try using the method I posted?  What are the results?  Can you post the script (at least the applicable portion)?

    • #284260
      Participant
      Topics: 2
      Replies: 8
      Points: 39
      Rank: Member

      Hi –

      I’m not sure what script you are looking for? I posted the Batch script above which calls a ps1 script I use to send emails. Nothing in the ps1 should matter for this exercise. I’m merely trying to ADD a peice to my ps1 to derive the batch script name.

      I tried your example but doesn’t make sense to me on how I can derive the batch script name from the ps1. Can you spin up an example of a batch script calling a ps1 and then trying to derive the batch script name from the ps1? Thanks!

    • #284275
      Participant
      Topics: 5
      Replies: 252
      Points: 999
      Helping Hand
      Rank: Major Contributor

      I’m merely trying to ADD a peice to my ps1 to derive the batch script name.

      The .ps1 script you are talking about in this quote is what I’m looking for. Isn’t that the script you want to find the batch script in?  If not where do you plan on putting this PowerShell code?

    • #284290
      Participant
      Topics: 2
      Replies: 8
      Points: 39
      Rank: Member

      Yes it is.  My apologies, I assumed you would use an example.  Here is the ps1:

       

      #::-- Param values passed in from Parent script in strict order --::#
      Param(
      #::-- Required & cannot be Null --::#
      [Parameter(Mandatory=$True)]
      [ValidateNotNull()]
      [string]$EmailSMTPServer,
      [Parameter(Mandatory=$True)]
      [ValidateNotNull()]
      [string]$EmailFrom,
      [Parameter(Mandatory=$True)]
      [ValidateNotNull()]
      [string]$EmailTo,
      #::-- Optional & can be Null --::#
      [string]$EmailPassword,
      [int]$EmailPort
      )

      #::-- Ensure email recipient string is in proper format --::#
      $EmailDelims = ("\)|\#|\$|\!|\%|\&")
      $EmailTo = $EmailTo.Trim() -replace $EmailDelims,","

      #::-- Check PowerShell Version --::#
      If($PSVersionTable.PSVersion.Major -lt 5) {
      Throw "WARNING : Please install PowerShell 5.0 or greater to be compatible with this script"
      Echo "WARNING : Please install PowerShell 5.0 or greater to be compatible with this script">>"$Env:LOGFILEemailerror"
      }

      #::-- Determine Cloud Environment --::#
      If("$Env:INTRAPATH") {
      If("$Env:CLOUD_URL" -ilike "*test*") {
      $EmailEnv = "[TEST]"
      } Else {
      $EmailEnv = "[PROD]"
      }
      }

      If("$Env:EMAIL_PSSWD") {
      $EmailSecurePassword = Get-Content $EmailPassword | ConvertTo-SecureString
      $EmailSecureCreds = New-Object System.Management.Automation.PSCredential ($EmailFrom, $EmailSecurePassword)

      $MailParams = @{
      SmtpServer = $EmailSMTPServer
      From = $EmailFrom
      To = $EmailTo.Split(',')
      Subject = $Null
      Body = $Null
      Port = $EmailPort
      Credential = $EmailSecureCreds
      UseSsl = $True
      Priority = $Null
      }
      } Else {
      $MailParams = @{
      SmtpServer = $EmailSMTPServer
      From = $EmailFrom
      To = $EmailTo.Split(',')
      Subject = $Null
      Body = $Null
      Priority = $Null
      }
      }
      #::-- Extensions to exclude from Email Attachments --::#
      $EmailExtArray = "*deletefile*.log","*.cmd","*.bat","*.exe", "*.ps1", "*.*emailerror"

      #::-- Determine if there are any Attachments --::#
      $EmailAttachments = Get-ChildItem "$Env:INTRAPATH" -exclude $EmailExtArray `&lt;/code&gt;<br />&lt;code&gt;| Where-Object { !( $_ | Select-String "0% loss" -quiet) } `
      | Where { !$_.PSisContainer } |
      Select -ExpandProperty FullName

      #::-- Add additional attachments if applicable handled in parent batch --::#
      $EmailAttachmentsExtra = @("$Env:MISMATCH_DMFILE", "$Env:IMPORTERROR_DMFILE")
      ForEach ($EAE In $EmailAttachmentsExtra) {
      If ($EAE) {
      If(Test-Path $EAE -PathType Leaf) {
      $EmailAttachments += $EAE
      }
      }
      }

      #::-- Define Attachment Parameter if applicable --::#
      If($EmailAttachments){$MailParams.Attachment = $EmailAttachments}

      #::-- Determine Script Success from Parent Script via ERR variable --::#
      If("$Env:ERR"){
      $MailParams.Subject = "WARNING : $ParentScript Failed $EmailEnv"
      $MailParams.Body = "The $EmailEnv $ParentScript process failed to complete successfully." + " n&quot; + &quot;n" + "Please the check log file(s) for additional details." + " n&quot; + &quot;n"
      $MailParams.Priority = "High"
      } Else {
      $MailParams.Subject = "ATTENTION : $ParentScript Succeeded $EmailEnv"
      If("$Env:INTRAPATH") {
      $MailParams.Body = "The $EmailEnv $ParentScript process completed successfully." + " n&quot; + &quot;n" + "Please the check log file(s) for additional details." + " n&quot; + &quot;n"
      } Else {
      $MailParams.Body = "The $EmailEnv $ParentScript process completed successfully." + " n&quot; + &quot;n"
      }
      $MailParams.Priority = "Normal"
      }

      #::-- Send Email --::#
      #::-- Redirect stderr to err file --::#
      Try {
      Send-MailMessage @MailParams -ErrorAction Stop
      }
      Catch {
      Echo "Failed to send message because: $($Error[0])"&gt;&gt;"$Env:LOGFILEemailerror"
      exit 1
      }

    • #284296
      Participant
      Topics: 5
      Replies: 252
      Points: 999
      Helping Hand
      Rank: Major Contributor

      Thanks for the script.  I did provide an example, but I don’t see where you tried to use it in this script.  Having said that, the formatting of the script is a little hard to read.  Make sure you are following the posting guidelines for scripts.  Recommend using the PowerShell_ISE format because it adds line numbers which would be easier to reference in a discussion post.

      When you get the batch file, what do you want to do with that data?  Include it in the email?

      • This reply was modified 2 weeks ago by Mike R..
    • #284353
      Participant
      Topics: 2
      Replies: 8
      Points: 39
      Rank: Member

      Yes, you’ll see the $ParentScript variable in the Subject/Body lines of code.  I need $ParentScript populated with the batch script name.

    • #284368
      Participant
      Topics: 5
      Replies: 252
      Points: 999
      Helping Hand
      Rank: Major Contributor

      Then assign the $ParentScript variable using the example I provided.  Something like…

       

    • #284374
      Participant
      Topics: 2
      Replies: 8
      Points: 39
      Rank: Member

      Ah thank you! I was forgetting the .Commandline portion on the variable!

       

      One last thing, $ParentScript is now populated as such:

      C:\WINDOWS\system32\cmd.exe /c “”C:\Cloud_Automation\Applications\AEW-Test\Scripts\Batch\_EPMAutomate_Cloud_Utility.cmd” ”

      is it possible to then parse that output to get everything between the “” symbols and then ONLY reutrn the string following the LAST \ symbol.

      For instance: _EPMAutomate_Cloud_Utility.cmd

       

      Possible? Thank you!

    • #284380
      Participant
      Topics: 5
      Replies: 252
      Points: 999
      Helping Hand
      Rank: Major Contributor

      is it possible to then parse that output to get everything between the “” symbols and then ONLY reutrn the string following the LAST \ symbol.

      Absolutely.  I previously posted an example of this.  You can use the -replace method with a regular expression. In this example I’m assuming they all end in .cmd.  If that’s not correct you’ll have to modify the regular expression to handle other extensions.

       

    • #284392
      Participant
      Topics: 2
      Replies: 8
      Points: 39
      Rank: Member

      Wow, thank you so much!! This is great!!

Viewing 15 reply threads
  • You must be logged in to reply to this topic.