Lately I have been developing PowerShell scripts on a Window 8 machine instead of on a Windows Server 2012R2 which I normally do.
I have encountered two very strange things that never happened on the server.
I know, two questions in one post, but I believe they might be connected.
After a while cmdlets just stop producing any output whatsoever, no error messages, no verbose output. It doesn't matter if I run it in the "lower" command part or in the "upper" script editor, and no difference if I run a selected part of the script or the whole thing. If I switch to a "normal" PowerShell the cmdlet works fine. If I restart PowerShell ISE, the cmdlet start working again, but only for a like 2-5 execution (not at all exact number) after which it stops working again. Not all cmdlets behave this way, mostly had problems with Storage related cmdlets (Format-Partition, Get-Disk, Get-Volume and so on).
After a while cmdlets that used to work fine in the "upper" script part of PowerShell ISE just stops working. The cmdlets still work fine in the "lower" command part of the ISE GUI, but does not work when used in the "upper" script editor, even though they did just a second ago. And it doesn't matter if I run the whole script or just a selected part. And by not working I mean it can't even find the cmdlet (The term '' is not recognized as the name of a cmdlet). The cmdlet is available in the Commands Side-Bar where it show up without any problem and I can access help for it.
So any ideas what is going on here?
Related
I'm a complete rookie to programming. I will say so much off the bat: please go easy on me. I simply want to know what happens on a system-wide level when I run a script through the PowerShell ISE program. If I run something in an IDE, I have always assumed that no system calls are made, meaning the script isn't communicating with the kernel or making actual changes to the OS. To the contrary, the script is simply being run in a sandboxed environment, as a test run for lack of better terms. I use the term sandboxed loosely here.
If I am on the mark here regarding how an IDE works, does PowerShell also work the same way. If I am incorrect overall with all of my observations, please correct me. I'm just a tad bit beyond the phase of a script kiddie. I can write simple Bash scripts and execute PowerShell commands but I am miles behind the talent of a developer or full-time programmer. Looking for an answer from a veteran to a rookie here.
The PowerShell ISE is called an Integrated Scripting Environment. It can be thought of as a stripped down Visual Studio or maybe instead an enlightened Notepad with a paired PowerShell console.
In any case, and maybe someone will chime in with the true history of the ISE here, the PowerShell console is just as effective and powerful as the Linux Bash Shell, or the Windows Command Prompt.
Commands you run in PowerShell use underlying Windows APIs or dotnet namespaces which can absolutely change the system.
For instance, you can start and stop services or even disable them, if you've got the permissions and are running as an administrator. That's definitely changing the underlying system.
Set-Service -Name Spooler -StartupType Disabled
You can also change registry keys you definitely should not be touching.
#Disable Windows Update
Set-ItemProperty -Path HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate -Name AU -Type DWord -Value "NoAutoUpdate"
Having permission to do these things depeneds on what your account can do. If you're running as a standard Windows user without admin rights, these calls will fail.
If you run the ISE or PowerShell without 'Run As Administrator', these calls will fail.
However, if you are an admin, and run PowerShell or the ISE as an Admin, you have effectively taken both safeties off and can now freely ventilate your foot.
Same goes for if you're running with a powerful Active Directory or Azure account. Only use those credentials when you need them, or your inevitable accidents will be truly remarkable, swift and terrible.
I am working on a number of Powershell cmdlets that form a relatively complex module. I have done so in the past, but this time a number of thing are changed...
I can not get a breakpoint to work. SOmehow VS does not seem to autoamtically want to connect to Powershell or Powershell Core runtime environments.
The Module is a class library that is made using the netstnadard2.0
Executable is set as
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
Arguments are
-NoLogo -NoExit -Command "Import-Module '.\Cli.dll'"
All works nice - Powershell windows opens, but breakpoints do not load. Period. Executing a Cmdlet also does not load them. I am attached to SOMETHING because i offers "detach from process".
Out of sudden, a colleague of mine found a script that runs during the startup of the Windows on his machine, which is found to be a powershell script.
The code is below, what I understood that it only minimizes all windows opened.
powershell -command "& { $x = New-Object -ComObject Shell.Application; $x.minimizeall() }"
I need to know if there is an impact from this code on his machine as to isolate from the network.
It doesn't seem to present a threat in and of itself. If someone is doing something unwanted, it would probably be that they're starting some other program that does something not nice, and this PowerShell command minimizes its window (possibly to the taskbar notification area where it can be hidden) so that you don't see what's going on. But the command itself appears harmless.
It only minimizes all the windows. Except that nothing else. I don't think it is harmful. If someone has kept it in the startup, I believe the reason being some other App is opening window in the startup , so it is trying to avoid that.
I can't post all of the script contenet, but the basic idea is that it downloads JSON and converts it to objects using the ConvertFrom-Json cmdlet. Some objects are filtered out, and the rest are written to an XML/XLS document (in the Excel 2003 format). This file is then attached to an email and sent to various people.
The problem I'm having is that it only works when run from the Powershell ISE. Once I try setting up a scheduled task, calling it from cmd, or even calling it from powershell, the attached file is completely empty. It is as if some functions do not run (the one that loops through and creates all rows).
I can continue to run from ISE for the time being, but the idea of this script is to send out an automatic email that will require no intervention. Any ideas as to what could be causing this?
You need to run the script "dot sourced"
which can be done like this
powershell.exe -noexit -file c:\test.ps1
or
pwershell.exe -noexit ". c:\test.ps1"
See this link under the -File section
http://technet.microsoft.com/en-us/library/hh847736.aspx
Based on the answer from the comments to the original post, it seems that the script was (unexpectedly?) working in the ISE because of the bug/quirk/feature that allows scripts run in the ISE to be aware of variables used in the console window and vice-versa.
This can often cause logic problems or unexpected results when a script runs with a variable already defined (and not initialized carefully in the script).
Ways to avoid this problem:
Try to test your code in as clean an environment as possible.
http://powershell.com/cs/blogs/tips/archive/2015/02/12/getting-a-clean-powershell-environment.aspx
To make sure a script runs in a completely clean test environment, you
could of course restart the PowerShell ISE. A more convenient way is
to open another PowerShell tab: in the PowerShell ISE, choose File/New
PowerShell Tab.
Use Set-StrictMode 2 in your script to catch undefined variables, etc.
https://technet.microsoft.com/en-us/library/hh849692.aspx
Set-StrictMode -Version 2.0
Prohibits references to uninitialized variables (including uninitialized variables in strings).
Prohibits references to non-existent properties of an object.
Prohibits function calls that use the syntax for calling methods.
Prohibits a variable without a name (${}).
I have had this problem be for and for me executing the scrip using single-threaded function from powershell worked.
You could also try some other options, go to this link to find more info.
Example
powershell.exe -noexit c:\test.ps1 -sta
Change the missing variable or function to global.
function global:mycall{}
Start your Script with:
[cmdletbinding()]
I try to figure out whether my script is running in PowerShell.exe or in the ISE. If I am running in PowerShell.exe then I would like to change the size of the console window, but I don't want to impact the ISE, if I don't.
You can look at the $Host variable. The name will be "ConsoleHost" in the console and "Windows Powershell ISE Host" in the ISE. Although this can probably be a little flaky to test because you're relying on user-readable strings.
Another way might be to look at $Host.UI.RawUI.BufferSize.Height which seems to be always 0 in the ISE. Something which isn't very common with a console window.
$shellid also, however a better option would be to use the separate profiles for each host:
Microsoft.PowerShell_Profile.ps1 and Microsoft.PowerShellISE_Profile.ps1. The respective files will run for the specific hosts. To run something in all hosts use the generic, Profile.ps1