How are PowerShell Modules (particularly PSReadline) loaded automatically in V5? - powershell

I recently installed Windows 10, which includes V5 of PowerShell, or 5.1.14393.206 to be exact ($PSVersionTable.PSVersion).
On new computers I install PSReadline. However, Windows 10 comes with it already installed.
My question is, how is PSReadline loading automatically, when there is no profile to import it, (or call a command from it)?
As proof, I ran this code:
$PROFILE | Get-Member -MemberType NoteProperty | % {
$path = $PROFILE.$($_.Name);
$exists = Test-Path $path;
[pscustomobject]#{ Path = $path; Exists = $exists }
}
To get this:
Path Exists
---- ------
C:\Windows\System32\WindowsPowerShell\v1.0\profile.ps1 False
C:\Windows\System32\WindowsPowerShell\v1.0\Microsoft.PowerShell_profile.ps1 False
C:\Users\tahir\Documents\WindowsPowerShell\profile.ps1 False
C:\Users\tahir\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1 False
I have gone through all of https://stackoverflow.com/a/23942543/288393:
No call to Import-Module for PSReadline is made because there are no profiles to call it.
No commands within PSReadline module are made because, as before, there are no profiles to call it.
Can someone explain this behavior?

There is special code in the console host to load PSReadline if the process is interactive. You can see the code here.

PSReadline is located in a pre-defined module folder C:\Program Files\WindowsPowerShell\Modules, because it's here PowerShell's automatic cmdlet discovery and module loading process will pick the module up and load it when any functions within it are called. That process added in PS v3.

Related

PowerShell Az module: export and import offline

I need to move PowerShell Az module from one machine to another offline (both machines have the same windows (10 Pro 1809), .net, powershell (5.1), etc versions)
I can't use either Private PowerShellGet Repositories or MSI installer
I run Save-Module -Name Az -Path 'C:\Users\kag\Documents\ps_modules' -RequiredVersion 3.7.0 -Force on "donor" machine and it gives me 50+ dirs exported:
I copy all to "receiver" machine and running:
Get-ChildItem "C:\Users\kag\Documents\ps_modules\*" -Recurse | Unblock-File
Import-Module -name "C:\Users\kag\Documents\ps_modules\Az" -Verbose
..but getting errors for all dependencies:
Any ideas how to correctly move Az module offline?
Here my comments as answer:
It seems the path you saved the module in C:\Users\kag\Documents\ps_modules is not one of the module paths PowerShell knows of.
You can test which paths are used by PowerShell to find your modules by typing
$env:PSModulePath.split(';')
in the console.
Below is an excerpt from Stefan Stranger's Blog
You can add a temporary path that is available for the current session only:
$env:PSModulePath = $env:PSModulePath + ";C:\Users\kag\Documents\ps_modules"
To make that permanent, you can either add the line above to your PowerShell profile, or manually add it to the registry:
$CurrentValue = [Environment]::GetEnvironmentVariable("PSModulePath", "User")
[Environment]::SetEnvironmentVariable("PSModulePath", $CurrentValue + ";C:\Users\kag\Documents\ps_modules", "User")
use "User" to store this path for the current user only. Use "Machine" to have that path available for all users

wlanapi.dll in powershell. Disable background scanning

Looking for some help with a script. I have tried and failed. I am not really advanced in powershell.
importing dlls is new for me. Any help is appreciated.
I want to use powershell to import the wlanapi.dll and use micrsoft native wifi functions to disable wireless background scanning, and enfore streaming mode.
The script should do this on execute. That way I can run it, or set it in a start up script.
https://learn.microsoft.com/en-us/windows/win32/api/wlanapi/nf-wlanapi-wlansetinterface?redirectedfrom=MSDN
Functions I am wanting to use:
wlan_intf_opcode_background_scan_enabled
wlan_intf_opcode_media_streaming_mode
Import is something you do via the PSModule paths where your modules or DLLs live.
You must tell PowerShell where the DLL is, no different than you'd have to if you loaded a module (.psm1 file with or without a manifest) of which you did not install to one of the defined PowerShell module paths.
You can use Add-Type...
Add-Type -Path $UncToCustomDll
... yet also, you can also use reflection:
$customDLL = 'UncToYourDLL'
See also Lee Holmes article on the topic here:
Load a Custom DLL from PowerShell
If you try to import and it's not in a know location, you get this.
Import-Module SomeNewCustomOr3rdP.dll
Import-Module : The specified module 'SomeNewCustomOr3rdP.dll' was not loaded because no valid module file was found in any module directory.
Of course, that error is pretty specific. It has no idea where to find it because that name does not match a module name.
So, this ...
Import-Module 'c:\users\mj\desktop\SomeNewCustomOr3rdP.dll'
Or create a folder of the same basename as the DLL in the PSModulePath, copy the DLL to the that named folder and use import as normal
C:\Users\<username>\Documents\WindowsPowerShell\Modules\SomeNewCustomOr3rdP\SomeNewCustomOr3rdP.dll'
Then this...
Import-Module SomeNewCustomOr3rdP
... should work as expected. All-in-all, Add-Type, Import-Module, and Reflection.Assembly::LoadFile($customDll), all accomplish the same thing, grant you access to the resource you specified.
If you are using a 3rdP DLL/Module, all this has to be done manually. If you are using published modules/packages that are in the MS powershellgallery.com, then this:
# Find all modules with wlan in the name
Find-Module -Name '*wlan*' |
Format-Table -AutoSize
# find all packages with wlan in the name
Find-Package -Name '*wlan*' |
Format-Table -AutoSize
# Get the detail on wlanapi specifically
Find-Package -Name 'wlanapi'
# Download and save a module or package
Find-Package -Name 'wlanapi' |
Save-Package -Path "$env:USERPROFILE\Documents\WindowsPowerShell\Modules"
Install-Package -Name 'wlanapi' -Force
Import-Module -Name wlanapi

remote IBM MQ monitoring from power-shell commands / scripts

I am trying to get queue depth for remote IBM MQ using PowerShell script/commands. Seems it is not working correctly, please help.
{
$myremoteconns = New-WMQQmgrConnDef -Name T.test.TEST.QM1 -Hostname abcd_testhost01 -Port 1111 -Channel T.test.MQMQ.TESTCHN
$qm = Get-WMQQueueManager -Connections $myremoteconns | where {$_.Name -like 'T.test.TEST.QM1'}
Error New-WMQQmgrConnDef the term 'New-WMQQmgrConnDef' is not recognized
Already installed WebSphere MQ - Windows PowerShell Library from below.
http://www-01.ibm.com/support/docview.wss?uid=swg24017698
Thanks
This error means that PowerShell cannot find this cmdlet. You need to check if the module you installed is properly found by PowerShell. Check this first:
Get-Module -ListAvailable
The result will be like:
PS C:\Users\username\PowerShell> get-module -ListAvailable
Directory: C:\Program Files\WindowsPowerShell\Modules
ModuleType Version Name ExportedCommands
---------- ------- ---- ----------------
Script 3.0.1 ImportExcel {Import-Html, ConvertFrom-ExcelSheet, PieChart, Import-UPS...}
If you don't find the module on the list you can import it manually using:
Import-Module -Name 'C:\path\to\module.psm1'
In PowerShell (starting at V3) modules should be imported automatically if they are inside on of the path specified in environment variable PSModulePath. You can check its value by using:
$env:PSModulePath
Once you know which folders are included in this variable you can either move the module there or just add another path using
$env:PSModulePath = $env:PSModulePath + ";c:\path\to\module"
This will work for current session. If you want to modify it for all session you can add the line below to PowerShell profile.
More info:
Importing a module
Modifying PSModulePath
PowerShell profiles

Specific PowerShell Module Not Autoloading

Im using PowerShell 4 on Windows Server 2012 R2.
A specific module, WebAdministration, does not get auto loaded when calling a Cmdlet that comes from this module. All other modules I have tried auto load successfully. I can load this module manually using Import-Module and it behaves as expected.
The PSModulePath environment variable contains the path with the module. Other modules from this path auto load.
The module is not custom. It is a built in IIS feature. The feature is enabled.
AutoLoading is enabled. $PSModuleAutoLoadingPreference is set to "All"
Get-Command "Get-WebBinding" doesn't work, but Get-Command | where {$_.Name -eq "Get-WebBinding"} does.
Get-Module -ListAvailable | where { $_.Name -eq "WebAdministration"} returns the module with the correct path.
PSModulePath = %SystemRoot%\system32\WindowsPowerShell\v1.0\Modules\
WebAdministration Module Path = C:\Windows\System32\WindowsPowerShell\v1.0\Modules\WebAdministration
Output from simple test
PS C:\Users\Administrator> $PSModuleAutoLoadingPreference = "All"
PS C:\Users\Administrator> Get-WebBinding
Get-WebBinding : The term 'Get-WebBinding' 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 is correct and try again.
At line:1 char:1
+ Get-WebBinding
+ ~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Get-WebBinding:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
PS C:\Users\Administrator> Import-Module WebAdministration
PS C:\Users\Administrator> Get-WebBinding
protocol bindingInformation sslFlags
-------- ------------------ --------
http *:8082: 0
http *:8081: 0
Any suggestions on why the auto loading isn't working would be greatly appreciated. Thanks!
Here's how I chose to load modules when I start up ISE each time. This gives me the option to load certain modules. I know this isn't what you asked for, but this does automatically load modules, and be sure to note how these modules are called.
Create the following file:
Path: C:\Users\<username>\Documents\WindowsPowershell
File: Microsoft.PowerShellISE_profileX.PS1
In the file, I use this code, but modify as needed:
$a = new-object -comobject wscript.shell
$intAnswer = $a.popup("Connect to Office 365?",0,"Office 365",4)
if ($intAnswer -eq 6){
#YES - Go to Cloud
#$a.popup("You answered yes.")
Set-Location H:\sandbox
#. .\Start3.ps1
. .\Auto-Connector.ps1
. .\Refresh-PSSession.ps1
. .\ScriptLoaders.ps1
. .\ESDSCRIPTS3.ps1
}else{
Set-Location H:\sandbox
Import-Module ActiveDirectory
}
I would consider using the #Requires statement at the top of the script file after you have imported it for the profile that the script will be running under. The script will likely not run unless it can find the module that the script requires. You then do not need to use the 'import-module' cmdlet as its already handled for you. You can read more about the requires statements here.
for example:
#Requires -Modules WebAdministration
Try reinstalling the module to see if that makes a difference.
If that doesn't work, while it's annoying that the autoload isn't functioning, you can import the module before use and expect it to work.
Import-Module WebAdministration
Get-WebBinding
Or if you need a one-liner:
Import-Module WebAdministration; Get-WebBinding
The only real clue I can find on why this may not work is that modules using providers may not autoload. WebAdministration provides the IIS: PSDrive. However, as I've indicated in a previous comment, I am able to autoload the WebAdministration module on WS 2016 with PS 5.1 installed, which goes against this statement. My hypothesis is this limitation might not be relevant in PS 5.1+, but I can't say for certain since I don't have a PS 4.0 env to test with.

How can I find the Microsoft Edge version on Windows 10 in powershell?

I've searched through the SOFTWARE\Classes and SOFTWARE\Microsoft subkeys, but couldn't find anything related to "spartan" or "edge". Given that Edge is still very new, there really isn't much information about this yet.
As an example, this is how I gather the information about the Internet Explorer Version via the registry on a remote machine:
$ieVersion=[Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey('LocalMachine', $args[0]).OpenSubKey('SOFTWARE\Microsoft\Internet Explorer').GetValue('SvcVersion')
Use the Get-AppxPackage command:
Get-AppxPackage -Name Microsoft.MicrosoftEdge | Foreach Version
The package name is valid on build 10240 but if you are on an earlier build, it might be different. If the above doesn't find the package try -Name *Edge* or -Name *Spartan*.
$productPath = $Env:WinDir + "\SystemApps\Microsoft.MicrosoftEdge_*\MicrosoftEdge.exe"
If(Test-Path $productPath) {
$productProperty = Get-ItemProperty -Path $productPath
Write-Host $productProperty.VersionInfo.ProductVersion
}
Else {
Write-Host "Not find Microsoft Edge."
}
Source How to determine the version of Microsoft Edge browser by PowerShell
For Edge on Chromium above 44 version
powershell:
Get-AppxPackage -Name *MicrosoftEdge.* | Foreach Version
cmd:
powershell "Get-AppxPackage -Name *MicrosoftEdge.* | Foreach Version"
I tested using two commands back to back. I ran from an elevated PowerShell session New-PSSession -ComputerName "The remote PC I was testing this on." and then once the connection was made I ran the Get-AppxPackage -Name Microsoft.MicsrosoftEdge and it pulled down the information, but I think it was more build information. You can also filter it down to version using the Pipe character. The full command looked like this.
Get-AppxPackage -Name Microsoft.MicrosoftEdge | select-object Version
I found this forum and others that lead me to some of the other switches and parameters I did not know about.
How can I find the Microsoft Edge version on Windows 10 in powershell?
I was trying to find an alternate way of remotely finding out what browser version it was. Trying to verify if it is updating regularly. I am still learning. I hope this helps. I found another article that shows me exactly what I am looking for differently without powershell.
https://www.tenforums.com/tutorials/161325-how-find-version-microsoft-edge-chromium-installed.html#option2
You may see multiple versions of Edge installed via Appx-Packages. I would recommend this approach:
$EdgeExe = Get-ItemPropertyValue 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\msedge.exe' "(default)"
$version = (Get-Item $EdgeExe).VersionInfo.ProductVersion