- Create a certificate-signed RDP shortcut via Group Policy - Fri, Aug 9 2019
- Monitor web server uptime with a PowerShell script - Tue, Aug 6 2019
- How to build a PowerShell inventory script for Windows Servers - Fri, Aug 2 2019
PowerShell Desired State Configuration (DSC) is a powerful, declarative language that allows administrators to guarantee a server stays the way you want. Whether you simply want to ensure certain registry keys exist, check that files are in a certain place or provision entire servers from scratch, virtually anything is possible with DSC.
DSC has a resources concept, which represents different sets of functionality. To install software onto a machine with DSC requires the Package resource. This allows you to define an installer package you'd like to install on a machine.
When DSC is invoked, this resource will first check to see if the software is already installed. If not, it will proceed to run the installer to get the software installed. Although the Package resource has some setbacks, it's still a good way to get "well behaved" packages installed on a number of machines.
For this article, I'm going to demonstrate installing the 7-Zip x64 MSI package with the Package resource, though you can also install EXE packages. You'll see that the 7-Zip MSI package works well with DSC, but not all MSI packages work equally as well. It depends on how the MSI was packaged.
First, you need to have PowerShell v4 or later installed. Otherwise, DSC is not available. You can always check this by typing $PSVersionTable.PSVersion.Major into the console. Once you've confirmed a current version, the next step is to ensure the Package resource is available by running Get-DscResource.
Get-DscResource-Name Package
If it is available, you should see the Package resource properties.
Package resource properties
I'll be installing 7-Zip on a single, local machine, so I'll need to check that the package exists on that machine. This is not a requirement, however, for the Package resource. I'll be using DSC in "push" mode here. If you've got lots of servers to install software on, look into setting up DSC in "pull" mode.
I've downloaded and placed the 7-Zip MSI package on my computer at C:\7z1514-x64.msi. Now that it's in place, I'll need to install the package once manually to gather a proper name and product ID for the configuration script. This is an important step, as these attributes detect if the software is installed.
Once installed, I'll note the name and productID it was installed with. To do this, I'll use the Get-InstalledSoftware function in my SoftwareInstallManager module. Otherwise, you'll need to scour the HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall and HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall registry keys looking for the 7-Zip key.
Get-InstalledSoftware | where {$_.Name -match '7-zip'}
Retrieving the application name and product ID
Now that I have the proper name and product ID, I can create the DSC configuration script.
Configuration Install7Zip { Node $env:ComputerName { Package Install7Zip { Ensure = 'Present' Name = '7-Zip 15.14 (x64 edition)' Path = 'C:\7z1514-x64.msi' ProductId = '23170F69-40C1-2702-1514-000001000000' } } }
You can see above that I have a user-defined configuration called Install7Zip and am pointing the install to the local computer name. Inside, I'm referencing the Package resource and calling it Install7Zip as well. I'd like to confirm the software is present on the local machine, and I've filled in the values we collected earlier.
Once the configuration is built, we'll need to execute it like a simple PowerShell function. This will create a MOF file with the name of the local computer in the location of the output path.
Install7Zip -OutputPath C:\7Zip
Creating the MOF file
Once the MOF is generated, we just need to start the DSC configuration process by running Start-DscConfiguration-Path C:\Install7Zip-Wait-Verbose.
This will force DSC to first check that the software is installed. If not, it will run the MSI provided and install the software. By default, Start-DscConfiguration creates a job and runs in the background. Using the Wait parameter allows me to monitor the process as it goes along. You can see this process below.
Installing an application with PowerShell DSC
The beauty of DSC is that you don't have to code any of the usual logic required to check if the software is installed or not. Simply start the DSC configuration again, and it knows the software is already set up. It won’t attempt to run the MSI again.
Checking if an applications is installed
Installing software using the DSC Package resource can be advantageous for "well-behaved" EXE and MSI installers. However, as you attempt to deploy more software installers with it, you'll see that, due to the lack of standardization across many installers, it might not work as expected. If so, look into technologies like Choclatey or use PowerShell modules like my SoftwareInstallManager module to ease software deployments.
What package / where did you get the get-InstalledSoftware script?
6 years ago
It is available from my PowerShell module: SoftwareInstallManager.
How can I reference the exe from an Azure Storage Account?
5 years ago
I’m not for sure. You’d have to get it downloaded locally first.
where did you get the get-InstalledSoftware script?
5 years ago
It is available in my SoftwareInstallManager module.
Can DSC auto fill in settings for installing software (normally would be button presses to configure some settings)
3 years ago
Hi,
Check the below article for package Auto Configuration.
https://4sysops.com/archives/managing-msi-installations-using-the-windows-installer-powershell-module/
I have porwerhsell 4.0.
When running the script it gives me an issue with the “Package ” command that does not exist. any ideas?
How to install from share location? In first step I map share folder with credentials, but I am getting an error:
PowerShell DSC resource MSFT_PackageResource failed to execute Set-TargetResource functionality with error message: The running command stopped because the
preference variable “ErrorActionPreference” or common parameter is set to Stop: Access is denied
+ CategoryInfo : InvalidOperation: (:) [], CimException
+ FullyQualifiedErrorId : ProviderOperationExecutionFailure
+ PSComputerName : localhost
The SendConfigurationApply function did not succeed.
+ CategoryInfo : NotSpecified: (root/Microsoft/…gurationManager:String) [], CimException
+ FullyQualifiedErrorId : MI RESULT 1
+ PSComputerName : localhost
i have tried this formet and its really works
thanks for this artical
Hi All,
I am using DSC script to deploy 7zip /notepad++ on remove VM. it worked well, however when i tried to add DacFx msi installation into this script and ran it, then it only installs then DacFx msi but not the 7zip and notepad++.
I am not sure what i am missing here.
Please help.
3 years ago
Hello Ritesh,
Could you share the DSC code/script you are using.
Windows has a limitation of allowing only one msi installation at a time. We need to have a workaround for that.
Of course if you install 64-bit Netbeans, it puts in a bad Nomodify dword under the uninstall registry that breaks get-itemproperty.
I am trying to use this provided in example.
Get-InstalledSoftware | where {$_.Name -match 'Name of Some Applicaiton'
I am executing locally but
It seems to be trying to go out to connect to remote computer which is my computer on the domain. With following error. What am I missing?
with the following error message : The client cannot connect to the destination specified in the
request. Verify that the service on the destination is running and is accepting requests.
I don't know how to get Product ID for any software installer file? May I know how did you get product id for Install7Zip ?
1 year ago
Its mentioned in the article – you can either use script that Adam provided or search these keys in registry for the ID.
HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall and HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall
Registry to get product ID for already installed software, but my question is to get product ID from installer package file like .exe .msi
DSC config file will need product ID to install any package in Windows.
Sometimes I cannot install customer specific software and get product ID from RegEdit and pass into my DSC script file.
1 year ago
You need to open the MSI. Something like Orca.
David F.