PowerShell - Respond to a Command response - powershell

I am trying to write a simple script that will execute a console command in Windows, which will always ask for a confirmation for overwriting the existing data. I thought something like the below would work, but it appears I was mistaken (and no surprise, write-host doesn't interact with the command line, I believe it simply puts text on screen). Can anyone provide some advice on how to handle this? I need to be able to execute the script through task scheduler on a weekly basis with no interaction.
Script:
Start-Process -NoNewWindow -FilePath pw -ArgumentList #"
threshold checkpoint create "WeeklyBackup" "WeeklyBackup"
"#
sleep -Seconds 3
$confirm = Select-String -pattern "About to over-write existing CheckPoint 'WeeklyBackup'." -Quiet
if ($confirm)
{
Write-Host "Y`r"
}
What I expect to see in the console:
D:\BMC_Software\ProactiveNet>pw threshold checkpoint create "WeeklyBackup" "Week
lyBackup"
About to over-write existing CheckPoint 'WeeklyBackup'. Do you want to proceed?
(y/n)
Then a user would hit Y and carriage-return and the process would be done. But I want this automated.
Thanks in advance for any advice.

echo "Y`r" | pw
This is typically used from batch files but it usually works just as well from PowerShell.

Related

PowerShell: Make an Installation Process Silent

I have a script that calls an application from Microsoft's Company Portal and automatically installs it. This launches Company Portal, potentially disrupting end user workflow. Is there any way to make this process run in the background? I tried to add an Argument List, but the process still launches Company portal. Any ideas? Thanks.
$OutputFile = "$env:WINDIR\TEMP\PythoncpInstall.log"
$Process = "companyportal:ApplicationId=e60a5520-dc39-4156-9223-825264cd5145"
$ProcessArgs = " /s -Wait -NoNewWindow"
##########ERROR LOGGING#####
Function Set-WriteToLog ($Write1)
{
Write-Host "$(Get-Date -format yyyy-MM-dd-hh-mm-ss)`t-`t$Write1"
}
#########START OF SCRIPT BODY#############
Start-Transcript -Path $OutputFile
start-process $Process -ArgumentList $ProcessArgs
sleep 10
[void][System.Reflection.Assembly]::LoadWithPartialName('System.Windows.Forms')
[System.Windows.Forms.SendKeys]::SendWait("^{i}")
Stop-Transcript
Without knowing more about the application and its installer, I'm not sure how if what I will suggest will work. Please share this information when you can.
What might help you is using Start-Process with -RedirectStandardInput and -WindowStyle.
-RedirectStandardInput will allow you to provide a text file that will be passed to standard input. This might let you provide input, depending on how the installer is implemented.
-WindowStyle would allow you to launch the process minimized or hidden.
Unfortunately, the way your code is currently written relies on SendKeys, which would in turn rely on the window being visible and focused.
Please let me know what installer you're using (if it's external), and I might be able to provide more help.

PowerShell Start-Job not creating or amending files

I am new to PowerShell and this is the first time I am attempting to use a job. I am running into an issue where I have a part of a script that looks for a file, creates it if it doesn't exist and then amends the file, and when I run the script (not as a job) it executes correctly, but when I put it in a job, it doesn't amend the file.
A much simplified example of what I have is this:
Start-job -Name HostCheck -ScriptBlock {
ForEach ($Host in (Get-Content -Path .\HostFile.txt) {
Add-Content .\somefile.txt "`nWrite something on a new line for $Host"
} | Out-Null
}
# Removes job once it is finished
Get-Job -Name HostCheck | Wait-Job | Remove-Job
Now I have tried adding | Receive-Job after the | Out-Null, but that didn't seem to change anything.
I've seen people write the entire script-block to a variable and just use the variable instead, so I am curious if that is a requirement (but I wouldn't think so).
Also, this might matter, I open the script with a .bat file that escalates the PowerShell console to admin as well as setting the execution policy of the process to Bypass. Now it seems that everything that runs in that console session or is kicked off by that console session (several scripts get ran, this is just part of one of them) seems to inherit those settings, but being new with jobs, I don't know if it would also inherit those settings, or how I would force it to (if not).
I discovered the problem:
-Your current working directory is lost when starting a job so my relative path .\somefile.txt would default to C:\Users\[Username]\Documents instead of the location where the .\somefile.txt resides.
I can get around this by using an absolute path, or I think there is a way to pass arguments to a job, but if anyone knows a better way to do this, please feel free to comment.
Here's a workaround, cd to the current dir of the caller.
start-job { cd $using:pwd; pwd } | Receive-Job -wait -auto

How do I get a Powershell process that was opened by another Powershell process?

I am running multiple PowerShell scripts at once. I would like to be able to wait on certain ones to finish before opening new scripts. Basically, I was thinking if I could find the command line option that ran it something like "powershell.exe -Path "<script dir>" that would do it.
I tried doing a Get-Process | gm to find any parameters that I could call to get that information and I didn't see any (doesn't mean they aren't there) I tried looking through Task Manager to see if I could view something through the gui that I could link to but that didn't help either.
I hope I can get something like
Start-Process -FilePath ".\<script>.ps1" -ArgumentList "<args>"
do
{
sleep 10
}
until ((Get-Process -ProcessName "PowerShell" | where "<paramater>" -EQ ".\<script>")
I need to wait until that process is done but I don't want to put a wait at the end of the Start-Process because after that Start-Process kicks off I need some other items to go to while my .\ is running. I just need it to wait before another section of script kicks off.
Have a look at the "Job" cmdlets https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_jobs?view=powershell-6
And the $PID automatic variable, this will give the process ID of the current PowerShell session.

How to close Outlook program gracefully without use's interact to backup PST files?

I need some help on this code, i use it into a batch file all day # 3 AM.
The goal is to close Outlook properly to make backup of Outlook PST file.
In a specific context, if some panel are opened like account parameter panel from Outlook, it cannot be able to do the action and the script is looping.
As i execute powershell script from a batch (.bat) like this start /wait PowerShell -NoLogo -WindowStyle Hidden -NoProfile -ExecutionPolicy Bypass -Command "& '%~dp0CloseOutlook.ps1'", the powershell script continues to work silently if i close my batch (powershell process continu to run with infinite loop).
In this case, if i go to other applications, he tries to make hotkey (ALT+Y), which could be dangerous.
Is there any way to modify Powershell script to do hotkey (ALT+Y) only in the Outlook application to prevent the script from interacting with other applications?
In order to avoid infinite loops in the background, can we also tell him to do 50 x ALT + Y to exit powershell script ?
This will avoid having a process that runs in a loop.
$isOutlookOpen = Get-Process outlook*
if($isOutlookOpen = $null){
# Outlook is already closed run code here:
}
else {
$isOutlookOpen = Get-Process outlook*
# while loop makes sure all outlook windows are closed before moving on to other code:
while($isOutlookOpen -ne $null){
Get-Process outlook* | ForEach-Object {$_.CloseMainWindow() | Out-Null }
sleep 5
If(($isOutlookOpen = Get-Process outlook*) -ne $null){
Write-Host "Outlook is Open.......Closing Outlook"
$wshell = new-object -com wscript.shell
$wshell.AppActivate("Microsoft Outlook")
$wshell.Sendkeys("%(Y)")
$isOutlookOpen = Get-Process outlook*
}
}
#Outlook has been closed run code here:
}
If you know a better way to improve this code to close Outlook properly, please advise :)
Just to be more precise, i don't want to make Shadow copy with Hobocopy, or Shadowspawn (new name), these tools are not able to handle quote with robocopy command, so there is no way possible to use it if you have space in paths... too bad !
Anyway, backing up Outlook pst files when Outlook is still open, regardless of program being used, is an invitation for problems (to play Russian roulette)
So it seems more secure to try to close Outlook to backup pst file as well.
Many thanks for all.

Get-Content with wait parameter doesn't update in Powershell

I'm trying to monitor a file using Get-Content $path -wait in Windows Powershell V3.0. Sometimes when I execute this command line in Powershell it will function as expected. But sometimes it will only execute (or at least it seems like) get-content but without the -wait parameter. Even though the file get's updated it won't be shown in Powershell. If I cancel the command and rerun it it will show the updated file content.
What do I need to do?
EDIT: It seems to update blocks after a while. But it's not real-time really.
Not allowed to comment (don't have a 50 reputation), so have to give an Answer....
Less for Windows (http://gnuwin32.sourceforge.net/packages/less.htm) with the +F or Shift-F option (http://www.commandlinefu.com/commands/view/1024/make-less-behave-like-tail-f.) showed updated file content where PowerShell "get-content $path -wait" did not.