Welcome › Forums › General PowerShell Q&A › Get Batch Script Name (Parant Process) from ps1 script
- This topic has 15 replies, 2 voices, and was last updated 2 weeks ago by
Participant.
-
AuthorPosts
-
-
January 4, 2021 at 8:34 am #283963
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.
-
This topic was modified 2 weeks, 1 day ago by
-
January 4, 2021 at 9:11 am #283999
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:
PowerShell1234$ParentPID = Get-CimInstance -ClassName win32_process -Filter "ProcessID=$PID" |Select-Object -ExpandProperty ParentProcessID$ParentProc = Get-CimInstance -ClassName win32_process -Filter "ProcessID=$ParentPID" -
January 4, 2021 at 10:01 am #284008
THank you! Can’t seem to derive the batch script name thought from the PID.
-
January 4, 2021 at 10:13 am #284011
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
-
January 4, 2021 at 11:10 am #284029
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:
PowerShell12$teststring = "C:\Windows\System32\test.cmd arguments.bat"$teststring -replace ".+\.cmd ", ""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
-
January 4, 2021 at 6:08 pm #284134
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.
-
This reply was modified 2 weeks, 1 day ago by
-
January 5, 2021 at 8:05 am #284248
Did you try using the method I posted? What are the results? Can you post the script (at least the applicable portion)?
-
January 5, 2021 at 10:26 am #284260
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!
-
January 5, 2021 at 10:58 am #284275
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?
-
January 5, 2021 at 11:49 am #284290
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 `</code><br /><code>| 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" + "n" + "Please the check log file(s) for additional details." + " n" + "n"
$MailParams.Priority = "High"
} Else {
$MailParams.Subject = "ATTENTION : $ParentScript Succeeded $EmailEnv"
If("$Env:INTRAPATH") {
$MailParams.Body = "The $EmailEnv $ParentScript process completed successfully." + " n" + "n" + "Please the check log file(s) for additional details." + " n" + "n"
} Else {
$MailParams.Body = "The $EmailEnv $ParentScript process completed successfully." + " n" + "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])">>"$Env:LOGFILEemailerror"
exit 1
} -
January 5, 2021 at 11:59 am #284296
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..
-
This reply was modified 2 weeks ago by
-
January 5, 2021 at 2:10 pm #284353
Yes, you’ll see the $ParentScript variable in the Subject/Body lines of code. I need $ParentScript populated with the batch script name.
-
This reply was modified 2 weeks ago by
simms740063.
-
This reply was modified 2 weeks ago by
-
January 5, 2021 at 2:51 pm #284368
Then assign the $ParentScript variable using the example I provided. Something like…
PowerShell1234$ParentProc = Get-CimInstance -classname win32_process -filter ("ProcessID={0}" -f (Get-CimInstance -ClassName win32_process -Filter "ProcessID=$PID" |Select-Object -ExpandProperty ParentProcessID))$ParentScript = $ParentProc.CommandLine -
January 5, 2021 at 3:30 pm #284374
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!
-
January 5, 2021 at 3:41 pm #284380
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.
PowerShell1$ParentScript = $ParentProc.CommandLine -replace '.+\\', '' -replace '.cmd.*','.cmd' -
January 5, 2021 at 4:02 pm #284392
Wow, thank you so much!! This is great!!
-
-
AuthorPosts
- You must be logged in to reply to this topic.