How to import an external DSC module into PowerShell environment? - powershell

I have Windows 10 / Windows 2016 TP5 (PowerShell 5.1). I want to use a PowerShell DSC module from GitHub in my configuration, for example xTimeZone.
What shall I do to be able to reference it with Import-DSCResource?
It's the first time I try to add a module other than from an installer-based product and maybe I am missing something obvious. Isn't there a git clone-based procedure like pip or gem utilise?
I verified the value of $env:PSModulePath and it has two directories defined: C:\Users\techraf\Documents\WindowsPowerShell\Modules;C:\Windows\system32\W
indowsPowerShell\v1.0\Modules.
I copied the contents of xTimeZone directory to C:\Users\techraf\Documents\WindowsPowerShell\Modules.
PowerShell does not see it. Tried to copy on different levels of the repository - all failed.
When running the example script I get:
At line:12 char:4
+ Import-DSCResource -ModuleName xTimeZone
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Could not find the module 'xTimeZone'.
At line:16 char:9
+ xTimeZone TimeZoneExample
+ ~~~~~~~~~
Undefined DSC resource 'xTimeZone'. Use Import-DSCResource to import the resource.
+ CategoryInfo : ParserError: (:) [], ParseException
+ FullyQualifiedErrorId : ModuleNotFoundDuringParse
Per advice from the answer, after moving the module from C:\Users\techraf\Documents\WindowsPowerShell\Modules to C:\Windows\system32\W
indowsPowerShell\v1.0\Modules the first error disappeared and I get only:
At line:16 char:9
+ xTimeZone TimeZoneExample
+ ~~~~~~~~~
Undefined DSC resource 'xTimeZone'. Use Import-DSCResource to import the resource.
+ CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException
+ FullyQualifiedErrorId : ResourceNotDefined

About DSC resources
DSC resources are, in essence, specialised PowerShell modules. The resource module must export Get, Set and Test-TargetResource commands (another option is available with PowerShell 5, but out of scope in the context of xTimeZone).
Resources are always deployed in the following structure:
<Modules>\<ModuleName>\DSCResources\<ResourceName>
Get-DscResource looks for "modules" inside the DSCResources folder, as a sub-folder of an existing module. If it can't see the resource you cannot use it.
xTimeZone
xTimeZone consists of:
A PowerShell module which contains little more than a manifest and some examples.
A DSC resource named xTimeZone.
Windows PowerShell cannot find the resource unless it's correctly deployed. These instructions apply for downloading the module.
Select the master branch and download the zip of the repository from: https://github.com/PowerShell/xTimeZone/tree/master
Extract the zip file to a folder.
Rename xTimeZone-master to xTimeZone.
Copy xTimeZone to C:\Program Files\WindowsPowerShell\Modules
Verify you can discover the DSCResource:
Get-DscResource
If, for some reason, you're having problems with Program Files\Modules, you might use:
C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\
However, as this area is part of the operating systems files it's a lower preference.
Configuration
Once you can discover the resource, you need to import it into each Configuration element in which you wish to use it.
Configuration SomeConfiguration {
Import-DscResource -ModuleName xTimeZone
# Nodes statement follows
}

*Not trying to answer, just wanted to put in additional feedback, but don't have enough stack-street-cred to add a comment...
Depending on the DSC you're trying to use, sometimes you have to copy the content from the "source" folder (that contains aforementioned "modules" and "DSCResources" sub folders) up to the root of the dscname you're trying to work with. In my instance I was using the SqlServerDsc (url below) and am not overly versed so it took a while to figure out what was going on.
https://github.com/dsccommunity/SqlServerDsc
I initially followed directions provided on github of extracting the zip to a PS accessible directory, but nothing new was accessible via get-dscresource. After seeing the syntax outlined by the poster above, I gave manually copying the content of the DSC's source folder to the modules/SqlServerDsc root a try, and everything came back gravy fries.
All I needed was to refresh my resource since some new methods came out and couldn't remember how I did it before... This is definitely different.

Related

"$env:userprofile" does not yield the same result as using "%userprofile%" in file explorer

I'm attempting to find a users downloads directory in powershell using this line:
$downloadDirectory = "$env:USERPROFILE\Downloads"
But I'm getting the following error:
Get-ChildItem : Cannot find path 'C:\Users\skewb\Downloads' because it does not exist.
At D:\Users\Skewb\Documents\repos\DotaMatchFinder\unzip_move_run.ps1:16 char:5
+ Get-ChildItem -Path $downloadDirectory
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (C:\Users\skewb\Downloads:String) [Get-ChildItem], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand
When I type the following into the file explorer %USERPROFILE%/Downloads
I'm taken to the correct path D:\Users\Skewb\Downloads
Is this intended? Do I need to find this directory another way?
Your symptom is mysterious (see bottom section), but can - probably - be bypassed with a solution that is conceptually preferable anyway:
Since, as zett42 points out, the so-called known or special folders (folders known to the system to have specific purposes) may be redirected to a location other than their default location, the robust solution is to ask the system for that location, via a symbolic name.
Unfortunately, that isn't quite as straightforward as one would hope:
$downloadDirectory =
(New-Object -ComObject Shell.Application).NameSpace('shell:Downloads').Self.Path
A third-party list of supported symbolic names can be found here; the official conceptual help topic about known folders is not shell-friendly, unfortunately.
As of PowerShell 7.1, there is no PowerShell-native way to query known folders, but there's pending GitHub proposal #6966 to change that.
While .NET does have an API, [System.Environment]::GetFolderPath($symbolicName), its set of special folders is incomplete, and notably doesn't include the Downloads folder.
(New-Object -ComObject WScript.Shell).SpecialFolders($symbolicName) is similarly incomplete with respect to the supported set of special folders.
Caveat: While it is tempting to try to get known-folder information from the registry, this is officially advised against - see this blog post by Raymond Chen.
As for your symptom:
My guess is that something in your PowerShell profile(s) accidentally redefines the USERPROFILE environment, which, while technically possible, is obviously ill-advised.

App-V 5 Package Import to SCCM via PowerShell Manifest Error

I am attempting to automate the import of App-V 5 packages into SCCMv1802 via PowerShell. I am using the suggested Add-CMAppvDeploymentType command, targeting the package manifest file. I get an error message (see below) referring to the package manifest file not containing a valid root node.
I have attempted to use different packages and manifest files to rule out a potential dodgy package, but I've ended up with the same result. Importing the packages manually via the GUI also works ok.
Add-CMAppVDeploymentType -ApplicationName $AppName -ContentLocation $ContentLocation -DeploymentType "AppV"
Here's the exact error message I get:
Add-CMAppVDeploymentType : The specified App-V package's manifest file
does not contain a valid root node At line:1 char:1
+ Add-CMAppVDeploymentType -ApplicationName $AppName -ContentLocation $ ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Add-CMAppvDeploymentType], InvalidDataException
+ FullyQualifiedErrorId : System.IO.InvalidDataException,Microsoft.ConfigurationManagement.Cmdlets.AppMan.Commands.AddAppvDeploymentTypeCommand
I’ve come across the solution. It turns out that the Add-CMAppVDeploymentType is deprecated and won’t work with App-V 5 packages. I have instead used the Add-CMAppv5XDeploymentType cmdlet which targets the .appv file instead of the manifest.
Add-CMAppv5XDeploymentType -ApplicationName $AppName -ContentLocation $ContentLocation -DeploymentTypeName "Appv5X"

How do I correctly install the PowerShell MSOnline module in Windows 8.1 Enterprise?

I'm trying to write some scripts for Azure Active Directory / Office online, and I'm completely unable to install the MSOnline powershell module. I've installed the Office Sign In Assistant version 7.2 (64-bit for my 64-bit machine). When I try to run the MSI installer for the PowerShell module, it says it can't find the sign in assistant. When I install the powershell module through PowerShellGet, and then run the commands, it fails with:
Connect-MsolService : The Microsoft Online Services Module is not configured properly. Please uninstall and then reinstall the module.
At line:1 char:1
+ Connect-MsolService
+ ~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (:) [Connect-MsolService], InvalidConfigurationException
+ FullyQualifiedErrorId : Microsoft.Online.Administration.Automation.InvalidConfigurationException,Microsoft.Online.Administration.Automation.ConnectMsolService
Connect-MsolService : Object reference not set to an instance of an object.
At line:1 char:1
+ Connect-MsolService
+ ~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OperationStopped: (:) [Connect-MsolService], NullReferenceException
+ FullyQualifiedErrorId : System.NullReferenceException,Microsoft.Online.Administration.Automation.ConnectMsolService
Is there any way to get this installed ? I've even changed the language of my system to US-English and installed the correct language pack (because I've run into issues before with things not installing correctly if the system language is not US English)
Found at least a partial answer here that worked (at least got the module working again for one of my accounts, the other one still fails and remains a mystery):
MSOnline can't be imported on PowerShell (Connect-MsolService error)
In my case, some registry keys were missing (I don't know why) and reinstalling didn't help. I imported the registry keys with one path adaption from another system and now it works. I used the following registry keys (just copy to a file powershell.reg, change InstallPath if necessary, and import):
Windows Registry Editor Version 5.00
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSOnlinePowerShell]
"Version"="1.0.0"
"InstallPath"="c:\\Program Files\\WindowsPowerShell\\Modules\\MSOnline\\1.0\\"
"InstallLanguage"="en-us"
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\MSOnlinePowerShell\Path]
"WebServiceUrl"="https://provisioningapi.microsoftonline.com/provisioningwebservice.svc"
"FederationProviderIdentifier"="microsoftonline.com"
Follow the steps to install the Azure AD Module here

Could not install module dependencies needed by the configuration (DSC)

I am trying out the new Desired state configuration stuff and trying to work with a new class resource. I have installed the pre-production preview of WMF 5.0 on all servers involved in the process.
I have a Http pull server setup where I have deployed my class resource to.
The target nodes are configured to get their resources from this server which they seem to be doing.
However when I try to push a configuration out to the target nodes that use this class resource I get the following error
Checksum for module DeploymentClass_1.0 doesn't match. Could not install module dependencies needed by the configuration.
+ CategoryInfo : InvalidResult: (root/Microsoft/...gurationManager:String) [], CimException
+ FullyQualifiedErrorId : WebDownloadManagerModuleMismatchChecksum,Microsoft.PowerShell.DesiredStateConfiguration.Commands.GetDscModuleCommand
+ PSComputerName : DDsTest002
I am not sure what the dependencies are that it needs as pretty much the same code wrapped up in the old powershell way of creating a custom resource works fine. Any ideas on how to identify the missing dependencies? Once identified any ideas on how I would make these automatically available to an nodes that require the resources without going and installing a bunch of stuff on each target node that needs them?
Answer Edit - With thanks to Dan1el42
Here is the modified code to generate the checksum that fixed this for me. As Dan suggested just adding the -Force flag to New-DscChecksum command did the trick.
$modulePath='M:\Modules\DeploymentClass'
#get module Version
$content=Get-Content $modulePath\DeploymentClass.psd1
$version=$content[14].Split("'")[1]
$version
$archiveFQN = 'C:\Program Files\WindowsPowerShell\DscService\Modules\DeploymentClass_' + $version + '.zip'
$archiveFQN
Compress-Archive -Path $modulePath -DestinationPath $archiveFQN -Force
New-DscChecksum $archiveFQN -Force
Looks like the checksum file DeploymentClass_1.0.zip.checksum does not match your DeploymentClass_1.0.zip. Please run New-DscChecksum again with the -Force switch.

Open a Solution from the Package Manager Console

I'm trying to automate the process of opening a solution from source control.
I have VS12 open, but no solution or project open. Is it possible to change directories and then open a solution from the Package Manager Console?
(This is kind of beside the point, but in case there is a better way overall to do this) I'm trying to script this so that a powershell module installed via nuget could be run:
PM> Get-MyProject 'SomeName'
The module would then from pwd get the latest source cd into it and open the solution. My module can already get the source, but I'm not able to figure out how to open the solution in powershell. It seems like $dte should be able to do it, but I tried:
PM> $dte.Solution.Open('NugetTest.sln')
I get back the error
Exception calling "Open" with "1" argument(s): " could not be found. (Exception from HRESULT: 0x80030002 (STG_E_FILENOTFOUND))"
At line:1 char:1
+ $dte.Solution.Open('NugetTest.sln')
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : COMException
The default directory for the package manager console (unless you have defined a profile where you change it) is %userprofile%. Probably not the place where your solution sits. If you write a powershell script and place it in your solution directory, then execute it from the Power Shell Console, you can get the path of your solution doing this:
$path = Split-Path -parent $MyInvocation.MyCommand.Path
You can create a solution like this:
$solution = $dte.Solution
$solution.Create("C:\Temp", "MySolution.sln")
The first argument indicates the directory where you want to create the solution, the second one is the name of the solution itself.
To open an existing solution:
$solution = $dte.Solution
$solution.Open("<path to your solution>")
If it doesn't work, your path is probably incorrect.