possible for PS script to install PS3 and continue on? - powershell

I have a PS script that automates server builds. Certain script operations require PS3.
The target environment is Windows Server 2008 R2 SP1 - which out-of-the-box includes PS2.
Is there a clever way for my script to install PS3 and then continue on ?
The goal is to trigger a single script to build the server.

Sure, there's probably a dozen crazy ways to do this. Let's tackle some high level concepts. So, how can might I structure such a script?
switch ($psversion.psversion.major) {
2 {
# trigger unattended install of powershell 3.0 forcing reboot
}
3 {
# do some powershell 3.0 specific stuff
}
}
So, that's a simple example of a single script that you might run twice, and the second time you run it, it will do something different. The other piece of the puzzle on how to run a script, reboot and continue the script can be read about here:
http://www.codeproject.com/Articles/223002/Reboot-and-Resume-PowerShell-Script
Hope this helps,

Related

Trying to get a Powershell Script that will run in a 2nd window and monitor in real time other running scripts / report all Errors / ExitCodes

I am fairly new to writing code in Powershell. For my job I have to write multiple Powershell scripts to make changes in the Hardware and Software settings as well as the Registry and Group Policy Editor to get these applications to run. These applications are a little older. Upgrading these software applications or the hardware then run on is NOT an option. as an example, when Microsoft releases the new patches on like Patch Tuesday...when those patches are applied there is a high probability that something will be changed which is where I come in to write a script to fix the issue. I have multiple scripts that I run. When those scripts are ran they may end up terminating because of an Error Code or an Exit Code. A large part of the time I do not that the script has failed immediately.
I am trying to figure out a script that I can run in a 2nd PowerShell Console Window. I am thinking that the only purpose of this script is to just sit there on the screen and wait and monitor. Then when I execute a script or Application (the only file extensions that I am worried about are: EXE, BAT, CMD, PS1) if the script/application that I just ran ends with an exit code or an error code....then output that to the screen...in REAL TIME.
Below, I have a small piece of code that kind of works, but it is not what I am wanting.
I have researched online and read and read tons of stuff. But I just can't seem to find what I am looking for.
Could someone please help me with getting a script that will do what I am wanting.
Thank you for your help!!!!
$ExitErrorCode =
"C:\ThisFolder\ThatFolder\AnotherFolder\SomeApplication.EXE # (this
would
# either be an EXE or CMD or BAT or PS1)"
$proc = Start-Process $ExitErrorCode -PassThru
$handle = $proc.Handle # cache proc.Handle
$proc.WaitForExit();
if ($proc.ExitCode -ne 0) {
Write-Warning "$_ exited with status code $($proc.ExitCode)"
}
Possible duplicate of the approaches shown here:
Monitoring jobs in a PowerShell session from another PowerShell session
Monitoring jobs in a PowerShell session from another PowerShell session
PowerShell script to monitor a log and output progress to another
PowerShell script to monitor a log and output progress to another

How to keep PowerShell process open with input/output on runtime?

I'm researching these days on how to can I keep a powershell process alive so I can run PS code without opening a new process each time.
The need:
- Running multiple PS scripts dynamically, so they have the same base (custom) modules, as efficient as possible.
Be able to communicate with stdout/stdin/stderr of these scripts process while it is still running.
Ideally I'd want one process to open with a docker, import my modules, and then collect the code itself to run, run it in the same process as the one already opened so it won't have to open another process nor import again my modules.
The problem:
- Setting up PS process in a docker container takes tremendous amount of time. (Roughly 2.5s, before I have even begun to run any code, and I'm talking about the PS process alone)
As of yet I did not find a PS way to run dynamic code on the same process without creating a new process & importing my modules again. Nor did I find a way to dynamically communicate with the new process while it still runs.
Possible Solutions:
- Create the initial PS process with -noprofile so it won't load so slowly. (I am yet to test this, but folks on redit seems to be approving of this method)
- Use start-process with -NoNewWindow flag, so it will generate new process each time but I guess the initial setup time will be spared.
- Trying to use Invoke-Expression on big chunks of code, but from what I understand that is not recommended and probably won't let actively communicate with the code running there until it finishes.
Start-Process -NoNewWindow
And
Invoke-Expression
Are the only relevant mechanisms I could find so far.
I've been told AWS lambda features similar functionality as what I am trying to achieve, but looking at it's code I did not make much progress, figured might be worth asking for help from people who are smarter then me :) Any help would be much appreciated.
I do not seek for already fully working 3ed side solution, simply being able to mimic that behavior in PS code would be good enough for me.

Why is the Uninstall-ChocolateyPackage cmdlet not recognized?

I am trying to run a PowerShell script to uninstall owncloud-client from my Windows 10 virtual machine. The code shown below can be found at
https://chocolatey.org/packages/owncloud-client (tools\chocolateyUninstall.ps1)
I would like just to test the code by running it from PowerShell to see if it actually uninstalls the software.
$unfile = "ownCloud\uninstall.exe"
if (Test-Path "${Env:ProgramFiles(x86)}\$unfile") {
$unpath = "${Env:ProgramFiles(x86)}\$unfile"
} else {
$unpath = "${Env:ProgramFiles}\$unfile"
}
Uninstall-ChocolateyPackage 'owncloud-client' 'exe' '/S' "$unpath"
I run script from the directory that contains it by typying:
.\chocolateyUninstall.ps1
As output I get the following error:
Uninstall-ChocolateyPackage is not recognized as the name of cmdlet, function, script file, or operable program.
The Uninstall-ChocolateyPacakge.ps1 package is provided by chocolatey. I checked on my machine and this package is present under:
C:\ProgramData\chocolatey\helpers\functions\Uninstall-ChocolateyPackage.ps1
but still it is not recognized as cmdlet by powershell. How can I solve this problem? thanks
When running the installation/uninstallation scripts, Chocolatey first includes the Chocolatey PowerShell module. This is done in the background, and normally, the end user doesn't need to worry about it.
For what you are trying to do, you will need to first do an Import-Module on the Chocolatey module, to bring it into the current PowerShell session. You can find this here:
old: C:\ProgramData\chocolatey\lib\chocolatey\tools\chocolateyInstall\helpers\chocolateyInstaller.psm1
new: C:\ProgramData\chocolatey\helpers\chocolateyInstaller.psm1
That should allow you to test the script directly.
Alternatively, you could run the install of the package, and then run the uninstall to see if it works as well.
With the latest moderation tools, you don't need to check every package (I mean, unless it makes you feel safer). You can always check the automated tests. There's a status dot to the right of the package title.
You can find the test summary
owncloud-client v2.1.1.5837 - Passed - Package Test Results
https://chocolatey.org/packages/owncloud-client/2.1.1.5837
Tested 10 Feb 2016 12:51:22 +00:00
Tested against win2012r2x64 (Windows Server 2012 R2 x64)
Tested with the latest version of choco, possibly a beta version.
Tested with chocolatey-package-verifier service v0.4.0-15-g979d0cc
Install was successful.
Uninstall was successful.
https://gist.github.com/choco-bot/45f343e23cc12e101130#file-_summary-md
or explore the uninstall log directly.
https://gist.github.com/choco-bot/45f343e23cc12e101130#file-uninstall-txt

PS1 uninstallation script in SCCM

I'm a nub scripter and am trying to write a really simple script to taskkill 2 programs and then uninstall 1 of them.
I wrote it in Powershell and stuck it in SCCM for deployment...however every time I deploy it, it's not running the last line to uninstall the program.
Here's the code:
# Closing Outlook instance
#
taskkill /IM outlook.exe /F
#
# Closing Linkpoint instance
#
taskkill /IM LinkPointAssist.exe /F
#
# Uninstalling Linkpoint via uninstall string if in Program Files
#
MsiExec.exe /X {DECDCD14-DEF6-49ED-9440-CC5E562FDC41} /qn
#
# Uninstalling Linkpoint via WmiObject if installed manually in AppData
Get-WmiObject -class win32_product -Filter "Name like '%Linkpoint%'" | ForEach-Object { $_.Uninstall()}
#
Exit
Can someone help? SCCM says the script completes with no error and I know it's able to execute it since the taskkills work...but it's not uninstalling the program.
Thanks in advance for any input.
So, SCCM is running this script, and nothing in the script is going to throw an error.
If you want to throw an error which SCCM can return to know how the deployment went, you need to add an extra step.
$result = Get-WmiObject -class win32_product -Filter "Name like '%Linkpoint%'" | ForEach-Object { $_.Uninstall()}
if ($result.ReturnValue -ne 0){
[System.Environment]::Exit(1603)
}else
{
[System.Environment]::Exit(0)
}
I see a lot of these kinds of questions come through on SO and SF: Someone struggling with unexpected behavior of an application, script, or ConfigMgr and very little information about the assumptions I can make about their environment. At that stage, it would typically be days of interaction to narrow the problem to a point where a solution is possible.
I'm hoping this answer can serve as a reference for future such questions. The first question to OP should be "Which of these 9 principles are you violating?" You could think of it as a sort of Joel Test for ConfigMgr application packaging.
Nine Steps to Better ConfigMgr Application Packages
I have found that installing and uninstalling applications reliably using ConfigMgr requires carefully sticking to a bunch of principles. I learned these principles the hard way. If you're struggling to figure out why an application is not working right under ConfigMgr, odds are that you will answer "no" to one of the following questions.
1. Are you testing the entire lifecycle?
In order to have any hope of reliably managing an application you need to test the entire lifecycle of an application. This is the sequence I test:
Detect: make sure the detection script result is negative
Install: install the application using your installation script
Detect: make sure the detection script result is positive when run
Uninstall: uninstall using your uninstallation script
I run this sequence repeatedly making tweaks to each step until the whole sequence is working.
2. Are you testing independently of ConfigMgr first?
Using ConfigMgr to test your application's lifecycle is slow and has its own ways of failing that can mask problems with your application package. The goal, then, is to be able to test an application's installation, detection, and uninstallation separate from but equivalent to the ConfigMgr client. In order to achieve that goal you end up with three separate scripts for each application:
Install-Application.bat - the entry point for your installation script
Detect-Application.ps1 - the script that detects whether the application is install
Uninstall-Application.bat - the entry point for your uninstallation script
Each of these three scripts can be invoked directly by either you or the ConfigMgr client. For applications installed as system you need to use psexec -s to invoke scripts in the same context as ConfigMgr (caveat).
3. Are you aware of context?
Installers can behave rather differently depending on the context they are invoked in. You need to consider whether an application is installed for a user or the system. If it is installed for the system, when you test independently of ConfigMgr, use psexec -s to invoke your script.
4. Are you aware of user interaction?
An installer can also behave rather differently depending on whether a user can interact with it. To test a script as system with user interaction, use psexec -i -s.
5. Did you match ConfigMgr to the tested context and user interaction?
Once you have the full lifecycle working, make sure you select the correct corresponding options for context (installed for user vs. system) and interaction (user can interact with application, or not). If you don't do this, the ConfigMgr client will be installing the application different from the way you tested, so you really can't expect success.
6. Are you aware of the possibility of application detection context mismatch?
The context that detection scripts run in depends on whether the application is deployed to users or systems. This means that in some cases the installation and detection contexts won't matched. Keep this in mind when you write your detection scripts.
7. Have you structured your scripts so that exit codes work?
ConfigMgr needs to see exit codes from your installation and uninstallation scripts in order to do the right thing. Installers signal failure or the need to reboot using exit codes. In order for exit codes to get to the ConfigMgr client you need to ensure that your install and uninstall scripts are structured correctly.
for batch scripts, use exit /b %errorlevel% to pass the exit code of your executable out to the ConfigMgr client
for PowerShell scripts, this is the only way I have seen work reliably
8. Are you using PowerShell scripts for detection?
ConfigMgr has a nice user interface for checking things like the presence of files, registry keys, etc as a proxy for whether an application is installed. The problem with that scheme is that there is no way to test application detection separately from and equivalent to the ConfigMgr client. If you want to test the application lifecycle independent of the ConfigMgr client (trust me, you want that), all your detection must occur using PowerShell scripts.
9. Have you structured your PowerShell detection scripts correctly?
The rules ConfigMgr uses to interpret the output of a PowerShell detection script are arcane. Thankfully, they are documented.

Executing a commandline from JConsole

I've recently discovered the joy of going through JConsole.exe instead of J.exe to run various scripts. There's generally a noticeable performance gain.
However, sometimes I need to use wd winexec (calling ad-hoc programs for example) and in the console, 11!:0 (wd) support is not available.
Is there a way to send a command from JConsole.exe to the regular Windows command line interpreter? Or maybe a workaround?
You might try the task script. See the script itself for documentation.
J6: ~system/packages/misc/task.ijs',
J7: ~system/main/task.ijs
It contains utilities such as fork_jtask_, spawn_jtask_, shell_jtask_
You can load the script in both versions using: require 'task'