Specific PowerShell Module Not Autoloading - powershell

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.

Related

Powershell does'nt recognize PnP cmdlets

im trying to use some PnP cmdlets and i keep getting the error:
Read-PnPProvisioningTemplate : The term 'Read-PnPProvisioningTemplate' is not recognized as the name of a cmdlet
Save-PnPProvisioningTemplate : The term 'Save-PnPProvisioningTemplate' is not recognized as the name of a cmdlet
i have already reinstalled the module a couple times and updated the Module too, but it doesnt show any affect.
my code is
$template = Read-PnPProvisioningTemplate -Path "C:\Users\Desktop\XMLs\Myfile7.xml"
Save-PnPProvisioningTemplate -Out myfile23.pnp -Template $template
Any Help would be great!

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

TFS 2017 build executing powershell failing due to term not recognized error on line 1

I'm pretty new to TFS and I'm still learning how to use it (so hopefully this isn't just a stupid oversight on my end). I'm working an internship this summer at a seasonal developer position, and essentially my end goal is to automate load testing for the company's website. I'm using TFS to achieve this goal; the build I currently have has two tasks only right now: one to start the controller and the testing environment, and one to stop them. My problem is that the build keeps failing before it really even starts, due to a "term not recognized" error on line 1, specifically caused by what appears to be the default working folder not being recognized.
Here are the relevant log files:
2019-05-30T20:00:02.0942883Z Executing the following powershell script. (workingFolder = D:\RM_agent\_work\11\s)
2019-05-30T20:00:02.0942883Z D:\RM_agent\_work\11\s
2019-05-30T20:00:02.4999117Z ##[error]. : The term 'D:\RM_agent\_work\11\s' is not recognized as the name of a
2019-05-30T20:00:02.4999117Z ##[error]cmdlet, function, script file, or operable program. Check the spelling of the
2019-05-30T20:00:02.4999117Z ##[error]name, or if a path was included, verify that the path is correct and try again.
2019-05-30T20:00:02.4999117Z ##[error]At line:1 char:3
2019-05-30T20:00:02.4999117Z ##[error]+ . 'D:\RM_agent\_work\11\s'
2019-05-30T20:00:02.4999117Z ##[error]+ ~~~~~~~~~~~~~~~~~~~~~~~~
2019-05-30T20:00:02.4999117Z ##[error] + CategoryInfo : ObjectNotFound: (D:\RM_agent\_work\11\s:String)
2019-05-30T20:00:02.4999117Z ##[error] [], CommandNotFoundException
2019-05-30T20:00:02.4999117Z ##[error] + FullyQualifiedErrorId : CommandNotFoundException
I know that the working folder defaults to $(Build.SourcesDirectory), so I'm assuming that D:\RM_agent\_work\11\s is what $(Build.SourcesDirectory) evaluates to. RM_agent is obviously an agent, so /_work/11/s should be the local path where it stores the source code. Why is it unrecognized then?
I tried manually setting the working folder for the scripts through tfs to the folder where the build is stored, but the build still failed and the logs still showed that workingFolder = D:\RM_agent\_work\11\s.
Additionally, the line of code that the build is failing on, Executing the following powershell script. (workingFolder = D:\RM_agent\_work\11\s), is nowhere in the script I am trying to execute, which confuses me. Where is this script coming from?
(I can remove this if it doesn't fit the guidelines/is off topic, but if anyone could point me towards any resources about tfs and/or load testing it would be massively helpful as well)
EDIT: Here is the powershell script for the first task
########################################
# start environment
########################################
# import modules
Import-Module '\\neenah-san1\TSbuild\Deployment\Tools\PowerShell\Azure\JJK.TS.Azure.psm1' -Force -Prefix 'TS'
# provide azure credentials
$credential = Get-Credential
# login to azure subscription
Login-AzureRmAccount -Credential $credential
# start the controller
Get-AzureRmVM -ResourceGroupName 'TS-LoadTest-TST' | Where-Object {$_.Name -match 'vstc'} | Start-TSAzureVM -Credential $credential
# wait for controller to fully start
Start-Sleep -Seconds 120
# start the agents
Get-AzureRmVM -ResourceGroupName 'TS-LoadTest-TST' | Where-Object {$_.Name -match 'vsta'} | Start-TSAzureVM -Credential $credential
# check status of all servers
Get-AzureRmVM -ResourceGroupName 'TS-LoadTest-TST' -Status | Sort-Object -Property Name | Select-Object -Property Name, PowerState | Format-Table -AutoSize
Solution structure:
EDIT 2: [RESOLVED] It's all fixed now, thank you! I went into the repository and mapped the folder my scripts were in directly to $(build.sourcesDirectory). Consequently I was able to change the file path to $(build.sourcesDirectory)\StartControllerAndAgents.ps1 and the build is now able to find the files to run.
You need to specify the path to the script as $(Build.SourcesDirectory)\Path\To\Script. Not the TFVC path which you've configured now $/Project/Path/To/Script.
The exact path depends on the workspace mapping of the build definition.
The same applies to the working directory.
There are a number of variables in Azure Pipelines (the current name for the Build hub in TFS/Azure DevOps) that resolve to different standardized paths on the agent. Almost all tasks take a relative path off of those variables.

Error while doing Get-Module in powershell 2.0

I'm new to powershell.I'm facing an error while working on an existing script.
In C:/Scripts I have 3 files . One .ps1 file and 2 .psm1 file.
ps1 file Name : RunScript.ps1
This imports .psm1 files like below.
$modules = #(
"$PsscriptRoot\Modules\Module1.psm1",
"$PsscriptRoot\Modules\Module2.psm1"
)
foreach ($module in $modules) {
if (-not $(Get-Module $module)) {
Import-Module $module -Force -WarningAction SilentlyContinue
}
}
This above code is giving me error as below
Get-Module : Running the Get-Module cmdlet without ListAvailable
parameter is not supported for module names that include a path. Name
parameter has this element 'C:\Scripts\Modules\Module1.psm1' which
resolves to a path. Update the Name parameter to not have path
elements, and then try again.
It is expecting to not give path of the file. But how do I do Get-Module in this scenario. Any help is very helpful.Thanks.
Get-Module returns modules imported into the current session or modules installed that are available for you to import. You should install your module then it will be available with the get-module cmdlet by using the name of your module.
I'm not quite sure what you're trying to do with your script? You only want to import it if its not already imported?
I would have added this as a comment but I cant yet...

Update-Module not finding PSGallery repo in script as a scheduled task

I have a scheduled task which runs an exported function from my PowerShell module which is hosted at powershellgallery.com. The function performs a check against the built-in PSGallery repository to see if a newer version is available and if so, update it.
I've noticed my module is not being updated as it should and to troubleshoot the issue I've redirected the output from two separate commands. First, to make sure the repository is 'visible' to the SYSTEM account running the task I run:
Get-PSRepository *>> c:\repo.log
This yields the following output:
Name InstallationPolicy SourceLocation
---- ------------------ --------------
PSGallery Untrusted https://www.powershellgallery.com/api/v2
So the SYSTEM account running the function as a scheduled task can 'see' the repo; no problem. Next, the function runs the Update-Module command as such:
Update-Module -Name $ProductName -Confirm:$false -Force -Verbose *>> c:\update.log
This yields the following output:
Checking for updates for module '[removed by me]'.
PackageManagement\Install-Package : Unable to find repository 'https://www.powershellgallery.com/api/v2/'. Use
Get-PSRepository to see all available repositories.
At C:\Program Files\WindowsPowerShell\Modules\PowerShellGet\2.0.4\PSModule.psm1:12546 char:20
+ ... $sid = PackageManagement\Install-Package #PSBoundParameters
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Microsoft.Power....InstallPackage:InstallPackage) [Install-Package], Ex
ception
+ FullyQualifiedErrorId : SourceNotFound,Microsoft.PowerShell.PackageManagement.Cmdlets.InstallPackage
Lastly, I checked the module to make sure it is indeed associated with PSGallery by running:
Get-InstalledModule -Name $ProductName | fl
The output shows:
RepositorySourceLocation : https://www.powershellgallery.com/api/v2/
Repository : PSGallery
UPDATE: I decided to use the Install-Module with the -Force switch to 'update' the module instead as I couldn't get the other command to work. Oddly though, when I do a Get-InstalledModule -AllVersions I can clearly see a difference between a module installed interactively and one installed under the SYSTEM account (running as a scheduled task). Pay attention to the Repository column:
If I run the function interactively it works without issue.
If I run Find-Module -Name $ProductName from within the function it finds the module without issue.
Tried both solutions from other question to no avail...
Any idea why the Update-Module command can't find the repo??
I believe you are seeing the bug described in https://github.com/PowerShell/PowerShellGet/issues/349 . It's not really related to SYSTEM account. Simplest workaround until fixed version is released is to uninstall the module then reinstall it again. You should only have to do that once, and update-module should work thereafter.
UPDATE: This is resolved in newer builds of PowerShellGet.