PS1 script stops execution in the middle when run silently - powershell

I'm trying to set up a PS1 script to restart the Windows service on the remote machine. Script is supposed to be automatically run by PRTG platform (monitoring solution). Platform has built-in feature which allows you start script for you. Problem is that when PRTG runs the script it stops in a half way without error after the ‘Stop-Service’ cmdlet. When I remove it from the script then full script is run. I've tried different variations of the script but it's always like it stops when it finished execution of ‘Stop-Service’.
The script supposed to be run in silent mode by the PRTG. Do you have any idea what can be the cause of it or how to check it?
$service = Get-Service -ComputerName 123.123.123.123 -Name Tomcat
Stop-Service -InputObject $service -Force
Move-Item -Path "\\123.123.123.123\C$\Program Files (x86)\tomcat\logs\tomcat.log" -Destination "\\123.123.123.123\C$\Program Files (x86)\tomcat\logs\log_archieve"
Get-ChildItem "\\123.123.123.123\C$\Program Files (x86)\tomcat\logs\log_archieve\tomcat.log" | ForEach-Object {
Rename-Item $_.FullName "$BackupFolder$($_.BaseName -replace " ", "_" -replace '\..*?$')-$(Get-Date -Format "ddMMyyyy")_oldlog.log"
}
Start-Service -InputObject $service -Verbose

Related

Powershell Form watching wsusutil.exe until finished

This is my first form I'm making to accomplish a task, but also to learn how to do it. I'm making a simple front end for exporting and then importing WSUS data from a connected server to a disconnected server. I'm working on the export part now and I need to figure out how to start the export process, then once it is done then make the iso file.
Here is the button code I have so far, but not sure how to watch the WsusUtil.exe until it's done then proceed to the next task. I thought I could watch the process and when it's over move to the next step. But have not been able to make that work. I tried a do until, but it kept running the start-process over and over. Also when it starts it make a large black box with some message on it. I tried to use the -NoNewWindow but it did launched. WsusUtil.exe running
$btnStartExport.Add_Click({
$nicedate = get-date -UFormat %m-%d-%y #put in MM-DD-YY format
#progress bar for overall progress of steps 1 and 2 and individual progress bar for each steps
$WSUSUtilPath = "c:\Program Files\Update Services\Tools\"
$WSUSMetaDataPath = "c:\tools\wsusexport\"
$isotitle = "WSUS Offline Server update $nicedate"
$ProcessName = "WsusUtil" #process to watch until it's done
$isofilename = "WSUSSvrOffline-$nicedate.iso" #creates WSUS Offline Server update-11-14-2021.iso
#Step 1 Check if directory exists
Check-Path $WSUSMetaDataPath
#Step 1 - export the WSUS Metadata
Start-process -FilePath $WSUSUtilPath\WsusUtil.exe -ArgumentList #("export","$WSUSMetaDataPath\$nicedate-export.xml.gz","$WSUSMetaDataPath\$nicedate-export.log") -NoNewWindow -Wait
$wsusProcess = get-process WsusUtil -ErrorAction SilentyContinue
# Step 2 - create ISO
get-childitem "$WSUSMetaDataPath","$txtWSUSContentPath.text" | New-IsoFile -path $txtISOLocation.text+$isofilename -Force -Title $isotitle
#clean up medatadata directory
get-childitem -path $WSUSMetaDataPath -Include *.* -File -Recurse | foreach {$_.Delete()}
})
$frmMain.controls.add($btnStartExport)

Invoke-Command doesn't return to local machine but software is installed

The tl;dr: I'm puzzled as to why my script isn't returning back to the deployment machine. Does anyone have an idea why?
I was provided an EXE and a couple arguments to install some software. I'm using PowerShell's Start-Process to run it. The deployment machine is Win Server 2012 domain controller, logged in and being run as domain admin. The test machines are two Windows 10 Pro domained machines. All three have PS 5.1.
Being a silent install, there is no user interaction required. If I run the exact command locally, via RDP, or in a pssession, with just c:\Software.exe /silent /arg2removed, it installs and returns as expected.
The script runs fine up to a point. Nothing happens after Start-Process inside Invoke-Command 's -ScriptBlock. In a separate PowerShell window, I can use Enter-PSSession for each of the two client machines, and Get-Service and Get-Process both show the software's service and background processes, respectively. I can Ctrl+c on the deployment machine and get back to a prompt. No errors are reported at any time.
Here's the Start-Process chunk. I've read the help and it doesn't sound like I'm missing anything that would allow the ScriptBlock to finish. If I prepend Start-Process with Write-Host (like we all do), it echoes the command that would run and I get back to a command prompt on the deployment machine.
# Start the installer.
Start-Process `
-FilePath "C:\${using:SrcExe}" `
-ArgumentList "/SILENT", "/arg2removed" `
-WorkingDirectory C:\ `
-Wait `
-Verbose `
-ErrorAction SilentlyContinue `
-ErrorVariable InstallErrors
Here's most of the script. The only items before Invoke-Command are where I set up $ComputersToInstallOn, enter the credentials (yes I'm sure they're correct), and supply the path to the EXE.
Invoke-Command `
-ComputerName $ComputersToInstallOn `
-Credential $Creds `
-Verbose `
-ErrorAction SilentlyContinue `
-ErrorVariable InvokeCommErrors `
-ScriptBlock {
# Get and print the destination machine's hostname
$ThisMachine = Get-Content Env:\COMPUTERNAME ; $ThisMachine
# Print the current date and time
Get-Date
# Check if Sentinel processes are running. If not, assume it's not installed.
$S1Procs = get-process sentinel*
if([string]::IsNullOrEmpty($S1Procs)) {
# Sentinel isn't installed. Continue.
# Map a drive letter to $SrcFolder. Not theoretically necessary but Start-Process complains when copying with the UNC path directly.
New-PSDrive `
-Name S `
-PSProvider FileSystem `
-Credential ${using:Creds} `
-Root ${using:SrcFolder} `
-verbose
# List remote folder
Get-ChildItem S:\
# Copy the $SrcExe to C:\
Copy-Item `
-Path "S:\${using:SrcExe}" `
-Destination C:\ `
-Verbose `
-ErrorAction Stop `
-ErrorVariable CopyErrors
# Unmount drive
Remove-PSDrive S -verbose
# Verify EXE exists locally
Get-ChildItem -Path C:\${using:SrcExe}
# If there were copy errors, abort.
if ($CopyErrors) {
Write-Host "There was an error copying '${using:SrcExe}' to $ThisMachine. Aborting."
exit 1 } else {
# All good so far. Continue to install.
Write-Host "$(Get-Date -UFormat '%Y%m%d %H:%M:%S') : Starting install on ${ThisMachine}. You may need to Ctrl+C to return to the local machine. Check processes on each machine though."
# Start the installer.
Start-Process `
-FilePath "C:\${using:SrcExe}" `
-ArgumentList "/SILENT", "/arg2removed" `
-WorkingDirectory C:\ `
-Wait `
-Verbose `
-ErrorAction SilentlyContinue `
-ErrorVariable InstallErrors
# ScriptBlock doesn't seem to make it to anything after Start-Process.
# Remove the EXE.
Remove-Item "C:\${using:SrcExe}" -Verbose -ErrorAction SilentlyContinue
exit 0
# Get-Process -Name Sentinel*
# echo "Sleeping. Now would be the time to abort."
# Start-Sleep 15
}
} else {
Write-Host "Sentinel appears to be installed and running."
$S1Procs
Get-Service -Name Sentinel* | Where-Object { $_.Status -match "Running" }
exit 0
}
}
if($InvokeCommErrors){
Write-Host "There were some errors."
}
EDIT: Added some requested info.

Powershell Popup Box not showing when installing through SCCM

Not sure how to fix it but I think i have a hunch on why
I have a powershell script installs an applications but before it kicks off it shows a msgbox that simply displays a message to the user
The script works perfectly when I run it manually and even running it as the System account through psexec works as well
However when deploying this through SCCM - Software center, it installs without displaying the msgbox..
Now I think it might be because its not showing in the context of the current logged in user.. but I would of thought running it through Psexec as system would not work either...
Can anyone help? I have deployed it as an application through sccm using this script:
<#
.Date: 01-Jun-2016
.Ansys 16.2 Install Script
# Set up some Variables
$workingDirectory = (split-path $myinvocation.mycommand.path -parent)
# Display a warning message before installation begins
Add-Type -AssemblyName Microsoft.VisualBasic
[Microsoft.VisualBasic.Interaction]::MsgBox('Ansys 16.2 takes over 30 mins to install. Please do not log out or shutdown your computer during the installation. You can continue working as normal while it is being installed. Once complete you will see in Software Center say "installed" next to Ansys 16.2.', 'OKOnly,SystemModal,Exclamation', 'Warning')
# ***** Install Application ******
Start-Process -FilePath "$WorkingDirectory\ANSYS162_WINX64_Disk1\setup.exe" -ArgumentList "-silent -disablerss -licserverinfo `"::licensing-b`"" -Wait -ErrorAction SilentlyContinue
Start-Sleep -s 3
# ***** Delete Shortcut and unlicensed products *******
Remove-Item "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\ANSYS 16.2\Uninstall ANSYS 16.2.lnk" -Force -ErrorAction SilentlyContinue
Remove-Item "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\ANSYS 16.2\ANSYS Icepak 16.2.lnk" -Force -ErrorAction SilentlyContinue
Remove-Item "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\ANSYS 16.2\Aqwa" -Recurse -Force -ErrorAction SilentlyContinue
Remove-Item "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\ANSYS 16.2\ACP" -Recurse -Force -ErrorAction SilentlyContinue
Remove-Item "C:\ProgramData\Microsoft\Windows\Start Menu\Programs\ANSYS 16.2\ANSYS Client Licensing" -Recurse -Force -ErrorAction SilentlyContinue "#>
Make sure that you have checked "allow the user to interact with this program" option while deployment
click here to see how to set user interaction

Running bat file via powershell on multiple servers

I'm using powershell to try and run an installation script remotely on multiple servers, but have become a bit stuck.
Below is what I have so far. Computers.txt contains a list of all the servers I want to run the installation on. These all sit on the same domain. I then map a drive to browse to the share where the script is, and then run the installation script.
$computers = Get-Content -Path c:\temp\Computers.txt
New-PSDrive –Name “S” –PSProvider FileSystem –Root “\\dc1-app01\apps” –Persist
Start-Process -FilePath S:\createfile.bat
I expect I am missing quite a bit in order for this to work? The bat file itself is pretty complex so at the moment I do not want to change this to powershell.
The PC I am running from is also a trusted host on these servers.
Appreciate your input, I'm a powershell newbie
Thanks
I think you're missing the loop that runs through the list (array) of servers:
$VerbosePreference = 'Continue'
$Computers = Get-Content -Path c:\temp\Computers.txt
Foreach ($C in $Computers) {
Write-Verbose "Start batch file as a job on $C"
Invoke-Command -ComputerName $C -ScriptBlock {
New-PSDrive –Name 'S' –PSProvider FileSystem –Root '\\dc1-app01\apps' –Persist
Start-Process -FilePath S:\createfile.bat -Wait
} -AsJob
}
Write-Verbose 'Waiting for all jobs to finish'
Wait-Job
Write-Verbose 'Showing job results:'
Get-Job | Receive-Job
I've also made it a job, so you can run it on multiple servers at the same time.
To even more simplify things, you don't have to map a drive just try this in the ScriptBlock of Invoke-Command:
& '\\dc1-app01\apps\createfile.bat'

Powershell in NonInteractive mode

I use Octopus for our deployments. I have a problem with one of the Powershell scripts to control the deployment:
# stops running processes
$processes = #("Notepad",
"Firefox")
foreach ($process in $processes)
{
$prc = Get-Process -Name $process -ErrorAction SilentlyContinue
if (-not($prc -eq $null))
{
Write-Host "Stopping " $prc.ProcessName
Stop-Process -InputObject $prc -ErrorAction SilentlyContinue
}
}
The programs I try to stop are not the ones you see in the script above, but they represent what I am trying to do. Now the problem I have with it, is that it works well on one server, but not on another. Where it does not work, I get the error message:
Stop-Process : Windows PowerShell is in NonInteractive mode. Read and Prompt functionality is not available.
The script that works runs on Powershell 3.0, the one that does not work on Powershell 2.0. I cannot upgrade to Powershell 3.0 everywhere yet because the old servers run with Windows Server 2003. How can I make it work on PS 2.0?
Run with -Force:
Stop-Process -InputObject $prc -ErrorAction SilentlyContinue -Force
As C.B. suggested in the comment: -confirm:$false should also work. Rationale for this is as follows: -Confirm is a switch parameter. Switch parameters can only take arguments if you specify the parameter with a trailing colon and a value.
I just tried to use Remove-Item on the directory with children and got same message:
Remove-Item : PowerShell is in NonInteractive mode. Read and Prompt functionality is not available.
In my case -Recurse key has helped.