Why does Chocolatey hang when using Powershell ISE without the `-y` switch? - powershell

When using PowerShell ISE with Chocolatey to install applications, if I forget the -y switch, it hangs waiting on some sort of "confirmation" that's not popping up anywhere?
I have to Ctrl+Alt+Del to kill PowerShell ISE and Chocolatey and it leaves things in half-way state.
This is what it looks like below:

In addition to the comments to the OP above, regarding PowerShell ISE not supporting (most) interactive console applications...
It is worth remembering that the REPL window in PowerShell_ISE.exe is not just some sort of docked PowerShell.exe console. Most of the time the user experience is the same, but this hides a number of differences:
https://blogs.msdn.microsoft.com/powershell/2009/04/17/differences-between-the-ise-and-powershell-console/
Both these executables are host applications that run a PowerShell runspace (engine). You can even write your own application that "hosts" PowerShell. It is the host application that determines the user experience.
PowerShell.org: The Shell vs The host
Spiceworks.com: The Shell vs The Host
Writing a Windows PowerShell Host
And finally, for the most curious:
How PowerShell works
I think I wrote this answer more for my own benefit; it's a useful refresher for me as I get asked this by colleagues every now and again...

It's simply because PoSH ISE is not a thing to use for user interactive .exe commands.
If you .exe or whatever expects a response, when in the ISE you have to provide it.
You can easily prove this is not a Chocolatey thing by trying any other .exe that kicks out interactive stuff. For example, just type:
nslookup in the script pane and F8 to run it, or type it in the console pane and hit enter
Either way, the console will just hang, waiting for a interactive response that you cannot provide.
You can still use interactive commands like nslookup in the PoSH ISE, but you have to provide all parameters. For example:
nslookup microsoft.com
nslookup -type=mx microsoft.com
nslookup -q=soa microsoft.com
PS 5.1 even kicks out an error message now.
nslookup
Cannot start "nslookup". Interactive console applications are not supported.
To run the application, use the Start-Process cmdlet or use "Start PowerShell.exe" from the File menu.
To view/modify the list of blocked console applications, use $psUnsupportedConsoleApplications, or consult online help.
At line:0 char:0
You can easily shell out to the PowerShell console host temporarily this way.
Here is a function I have in my profile for such efforts.
Function Start-ConsoleCommand
{
[CmdletBinding()]
[Alias('scc')]
Param
(
[string]$ConsoleCommand,
[switch]$PoSHCore
)
If ($PoSHCore)
{Start-Process pwsh -ArgumentList "-NoExit","-Command &{ $ConsoleCommand }" -Wait}
Else
{Start-Process powershell -ArgumentList "-NoExit","-Command &{ $ConsoleCommand }" -Wait}
}
So, just type
scc -ConsoleCommand choco install winmerge
It'll pop the console host and stay open until you close it.
Update
As per request of - Alex Kwitny
PoSHGet default has only two repositories,
nuget
PSGallery
but you can add your own or another.
You use the below cmdlets to make this happen.
I have not had to use Chocolatey in a while, but taking a quick look and my archives, the below is what I used
Set up chocolatey repository
Find-Module
Get-Module
Find-Package
Get-Package
Get-PackageProvider
Get-PackageSource
Get-PackageSource -Provider chocolatey
Register-PackageSource -Name chocolatey -Provider Chocolatey -Trusted -Location http://chocolatey.org/api/v2/ -Verbose
Find-Module
Get-Module
Find-Package
Get-Package

Related

Programs running on Hyper-V with Invoke-Command hang

I'm trying to run my software on Hyper-V VM using powershell Invoke-Command, without success. Host OS -Windows 10. Guest OS - also Windows 10. VM Generation 1.
I did some simple experiments and found out this:
If I run
Invoke-Command -VMName MY_VM -Credential $Cred -ScriptBlock { calc }
then I can see launched calc.exe on the guest system right with UI.
But if I run mspaint or any non-Microsoft program, nothing happens. The program just hangs in the VM TaskManager without any effect.
I also tried to run several different programs using CLI calling Invoke-Command several ways, but got the same result.
What could be the problem?
The basic answer is that powershell remote connections (or any remote connection like rdp, ssh, etc) take place in a separate logon session, and can't really interact with each other.
There are two reasonable ways to do this:
Use PsExec - part of the microsoft sysinternals tools group.
# List sessions - note the session ID of the session you want the process to start in
quser /server:$computername
# Run a process remotely, specifying the logon ID
PsExec.exe -s -i $ID notepad.exe
Use a scheduled task that runs when you are logged in and is visible. You can do this with powershell's various New-ScheduledTask commands to create one, or follow this guide by Scripting Guy! using WMI Win32_ScheduledJob methods.
See use powershell to start a gui program on a remote machine for more details on both options, and a well-written description of why it's hard to do in windows.

Run executable in powershell without waiting for return

This is really basic, but I can't find the answer. The installer sets up my path so that I can just type the command:
ng serve
at the command prompt and the script runs. I don't want to wait for this program to finish (it's a server, after all). How do I launch the same script (it's a CMD script as far as I can tell) from Powershell without waiting for it to finish (and without having to find the source directory for the script)?
If it's acceptable to terminate the server when the PowerShell session exits, use a background job:
In PowerShell (Core) 7+
ng server &
In Windows PowerShell, explicit use of Start-Job is required:
Start-Job { ng server }
Both commands return a job-information object, which you can either save in a variable ($jb = ...) or discard ($null = ...)
If the server process produces output you'd like to monitor, you can use the Receive-Job cmdlet.
See the conceptual about_Jobs topic for more information.
If the server must continue to run even after the launching PowerShell session exits, use the Start-Process cmdlet, which on Windows launches an independent process in a new console window (by default); use the -WindowStyle parameter to control the visibility / state of that window:
Start-Process ng server # short for: Start-Process -FilePath ng -ArgumentList server
Note: On Unix-like platforms, where Start-Process doesn't support creating independent new terminal windows, you must additionally use nohup - see this answer.

Powershell running a cmdlet from a called script

I have a script that calls another script (with arguments). The called script contains the Install-WindowsFeature cmdlet. When I run the script, the called script runs, but returns the following error:
Install-WindowsFeature : The term 'Install-WindowsFeature' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path
Of course, I can run the cmdlet just fine from a PowerShell console. I can also run the called script from a PowerShell console and Install-WindowsFeature works fine. So, is it something to do with calling a script from a script that runs a cmdlet? Here is my calling code:
$script = "C:\Path\script.ps1"
$argumentList = #()
$argumentlist += ("-Arg1", "value")
$argumentlist += ("-Arg2", "value")
$argumentlist += ("-Arg3", "value")
Invoke-Expression "$script $argumentList"
In the called script, I called Install-WindowsFeature as below:
if ($someValue) { Invoke-Command -ScriptBlock {Install-WindowsFeature -Name RSAT-AD-Tools} }
I've also tried it as below:
if ($someValue) { Install-WindowsFeature -Name RSAT-AD-Tools }
12/16/16 EDIT: This script is running in a GUI built with Sapien PowerShell Studio. When I change the build type to "Native" it works. I have to reset my lab to check, but I suspect it will also run if I just run it in the x64 context. This article explains why I think this matters.
Running on Windows Server 2012 R2
Unless you've got a compelling reason for it, let's see if we can clean up your calling pattern a bit - and hopefully make your other issues go away by avoiding the contortionism.
Rather than creating your parameter list as a string, take advantage of parameter splatting. It's good to get out of the habit of treating PowerShell like other scripting languages that don't work with objects.
$splat = #{
Arg1 = "value1";
Arg2 = "value2";
Arg3 = "value3"
}
& c:\path\script.ps1 #splat
Using that on a script.ps1 something like this:
param(
$Arg1,
$Arg2,
$Arg3
)
Write-Host "Arg1 = $Arg1, Arg2 = $Arg2, Arg3 = $Arg3
You'll get an expected output of:
Arg1 = value1, Arg2 = value2, Arg3 = value3
Once you've got that, there's probably no reason to use Invoke-Command on the call to Install-WindowsFeature, unless you're leaving out details like invoking remotely to a server. Invoke-Command { Install-WindowsFeature } still works fine for me on Server 2012R2 with PowerShell 5, and there's no reason it shouldn't.
This assumes you're running this script on a Server that support Install-WindowsFeature, as the other comments point out. Client Windows doesn't support Install-WindowsFeature, and the RSAT tools are installed via a stand-alone RSAT .MSU package, which you manage differently.
Install-WindowsFeature is natively provided with Server Manager on Server 2012R2 - there's no need to Import-Module... unless you've done something to your profile or fouled up your modules folders. One of the earlier versions of Windows Server needed it - but that was a couple versions back. Likewise, Add-WindowsFeature was the old name - and it's still available as an alias for Install-WindowsFeature.
I'm assuming you've tried Install-WindowsFeature directly from the command line to ensure it's in working order, and Get-Module Install-WindowsFeature looks reasonable.
PS C:\Windows\system32> get-module ServerManager
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Script 2.0.0.0 ServerManager {Get-WindowsFeature, Install-WindowsFeature, Uninstall-Win...
While we're on the topic, there's very little reason to drop to DISM on Server that supports Install-WindowsFeature, and a number of reasons not to.
Server Manager and several other tools (including Win32_ServerFeature) rely on the feature states parsed and understood by the WMI provider used by Install-WindowsFeature. It's possible to enable the right set of features using DISM, but needs attention and detail. Enabling only "part" of a role and feature may get the functionality you want for specific cases, but the role or feature may not show up as installed in Get-WindowsFeature, may not be uninstallable via Remove-WindowsFeature, and may not offer relevant UI features in Server Manager like monitoring health of the role, viewing relevant events, or offering tools for administering it.
Install-WindowsFeature integrates with additional code from the role & features you're installing, and may run additional health and pre-requisite checks to ensure your correctly configured.
DISM featurenames tend to change more often than the role & feature name of Server Manager, so your script portability will be better.
There are other points, but I won't go into them since DISM was primarily a comment fork.
You are probably right, it seems like the script gets executed with x86 PowerShell. I want to share a snippet with you which I use for scripts that needs to run in a specific environment (e. g. x64 PowerShell).
The script restarts itself in a x64 PowerShell if its started as x86 process. Just put this at the top of your script:
# Reinvoke the script as x64 if its called from a x86 process.
if ($env:Processor_Architecture -eq "x86")
{
&"$env:windir\sysnative\WindowsPowerShell\v1.0\powershell.exe" -noprofile -file $myinvocation.Mycommand.path -executionpolicy bypass
exit
}
Also note that the Install-WindowsFeature cmdlet doesn't work on all windows versions so consider to use dism instead:
$featuresToInstall = #('RSAT-AD-Tools')
$dismParameter = #('/online', '/Enable-Feature', ($featuresToInstall | % { '/FeatureName:{0}' -f $_ }), '/NoRestart')
dism #dismParameter
The running environment determines what modules you have access to. When I created this project in PowerShell Studio, it took the default of x86 (a 32 bit environment). This worked but because I was running it on Windows Server 2012 R2 (a 64-bit environment) I did not have access to the powershell modules such as Import-Module and Install-WindowsFeature. Changing this to a x64 project resolved my issue.
In order to avoid this scenario, it is important to make sure you run PowerShell scripts and modules in the architecture that is native to the OS. You can do this by setting the project correctly (if using a tool like PowerShell Studio) or by verifying that you are running in the native mode for that OS with the code Martin Brandl provided.

Powershell remotely register COM dll by using regsvr32

I found on Internet, this ps script may work. But the result I get is: no error pops up, but also DLL not found in registry after running the script.
Invoke-Command -ComputerName $servername -ScriptBlock {regsvr32.exe "\\uncpath\some.dll" }
I tried in both "run as administrator" and normal PS console window, and windows remote management service is on on remote server.
Any idea?
You need to use the silent option of regsrv32 (/s):
Syntax
REGSVR32 [/U] [/S] [/N] /I:[CommandLine] DLL_Name
Key /u Unregister Server.
/s Silent, do not display dialogue boxes.
/i Call DllInstall to register the DLL.
(when used with /u, it calls dll uninstall.)
/n Do not call DllRegisterServer, you must use this option
with /i.
CommandLine An optional command line for DllInstall
/c Console output (old versions only).

Exiting VMware vSphere PowerCLI command prompt?

Is there a script to input to exit VMware vSphere PowerCLI command prompt after executing a set of script for example created of VM.
MY last line of my .ps1 script is shown below, but the exit does not work, after executing my script, the command prompt is still there, unlike windows command prompt as the exit command works but not in powercli.
New-VM -name $vm -DiskMB 10000 -memoryMB 4000
New-CDDrive -VM $vm -ISOPath $win7 -StartConnected:$true -Confirm:$false
$scsiController = Get-HardDisk -VM $vm | Select -First 1 | Get-ScsiController
Set-ScsiController -ScsiController $scsiController -Type VirtualLsiLogicSAS -Confirm:$false
Start-VM -vm $vm
Exit
My hunch is that this has more to do with powershell and little to do with PowerCLI. I'm also guessing that the window closes if you focus it and press 'Enter'. I ran into this when executing some powershell scripts long ago, but never came across a decent fix until this evening. It seems powershell waits on a Readline() call after executing the script.
The solution: include the flag -InputFormat None in your call to powershell.exe. In your case, I'd include it in the call to the PowerCLI executable, it ought to be passed through.
Resources:
This looks like a known issue from Microsoft's tracker.
These two questions reference the same fix:
Powershell and WiX
Powershell and MSDeploy
Please let me know if this works correctly, I'm not on a system with PowerCLI installed currently.
Good luck!