1+ # This script is a prototype for quickly creating DSC files.
2+
3+ # Powershell 7 Required
4+ if ($ (Get-Host ).version.major -lt 7 ) {
5+ Write-Host ' This script requires powershell 7. You can update powershell by typing winget install Microsoft.Powershell.' - ForegroundColor red
6+ Exit (1 )
7+ }
8+
9+ # Create a custom exception type for our dependency management
10+ class UnmetDependencyException : Exception {
11+ UnmetDependencyException([string ] $message ) : base($message ) {}
12+ UnmetDependencyException([string ] $message , [Exception ] $exception ) : base($message , $exception ) {}
13+ }
14+
15+ # Ensure the Winget PowerShell modules are installed
16+ if (-not (Get-Module - ListAvailable - Name Microsoft.Winget.Client)) {
17+ try {
18+ Install-Module Microsoft.Winget.Client
19+ } catch {
20+ # If there was an exception while installing, pass it as an InternalException for further debugging
21+ throw [UnmetDependencyException ]::new(" 'Microsoft.Winget.Client' was not installed successfully" , $_.Exception )
22+ } finally {
23+ # Check to be sure it acutally installed
24+ if (-not (Get-Module - ListAvailable - Name Microsoft.Winget.Client)) {
25+ throw [UnmetDependencyException ]::new(" `Microsoft.Winget.Client` was not found. Check that you have installed the Windows Package Manager modules correctly." )
26+ }
27+ }
28+ }
29+
30+ # Ensure the powershell-yaml module is installed
31+ if (-not (Get-Module - ListAvailable - Name powershell- yaml)) {
32+ try {
33+ Install-PackageProvider - Name NuGet - MinimumVersion 2.8 .5.201 - Force
34+ Install-Module - Name powershell- yaml - Force - Repository PSGallery - Scope CurrentUser
35+ } catch {
36+ # If there was an exception while installing, pass it as an InternalException for further debugging
37+ throw [UnmetDependencyException ]::new(" 'powershell-yaml' was not installed successfully" , $_.Exception )
38+ } finally {
39+ # Check to be sure it acutally installed
40+ if (-not (Get-Module - ListAvailable - Name powershell- yaml)) {
41+ throw [UnmetDependencyException ]::new(" `powershell-yaml` was not found. Check that you have installed the module correctly." )
42+ }
43+ }
44+ }
45+
46+ [System.Collections.ArrayList ]$finalPackages = @ ()
47+ $configurationVersion = ' 0.2.0'
48+ $Utf8NoBomEncoding = New-Object System.Text.UTF8Encoding $False
49+ $DSCHeader = " # yaml-language-server: `$ schema=https://aka.ms/configuration-dsc-schema/$ ( $configurationVersion -Replace ' \.0$' , ' ' ) "
50+
51+ do {
52+ $findResult = Find-WinGetPackage $ (Read-Host ' What is the Winget ID, or name of the package you want to add to the configuration file?' )
53+
54+ if ($findResult.count -ne 0 ) {
55+ # Assign an index to each package
56+ $findResult | ForEach-Object { $script :i = 1 } { Add-Member - InputObject $_ - NotePropertyName Index - NotePropertyValue $i ; $i ++ }
57+ $findResult | Select-Object - Property Index, Name, Id, Version | Format-Table | Out-Host
58+
59+ $packageSelected = $false
60+ while (-not ($packageSelected )) {
61+ Write-Host
62+ # Prompt user for selection string
63+ $selection = (Read-Host ' Select a package by Index, Name, or Id. Press enter to continue or skip' )
64+ $selectedPackage = $null
65+ # If user didn't enter any selection string, set no package as selected and continue
66+ if ( [string ]::IsNullOrWhiteSpace($selection ) ) {
67+ $packageSelected = $true
68+ } elseif ( $selection -in $findResult.Id ) {
69+ # If the user entered a string which matches the Id, select that package
70+ $selectedPackage = $findResult.Where ({ $_.Id -eq $selection })
71+ $packageSelected = $true
72+ } elseif ( $selection -in $findResult.Name ) {
73+ # If the user entered a string which matches the Name, select that package
74+ # Because names could conflict, take the first item in the list to avoid error
75+ $selectedPackage = $findResult.Where ({ $_.Name -eq $selection }) | Select-Object - First 1
76+ $packageSelected = $true
77+ } else {
78+ # If the name and ID didn't match, try selecting by index
79+ # This needs to be a try-catch to handle converting strings to integers
80+ try {
81+ $selectedPackage = $findResult.Where ({ $_.Index -eq [int ]$selection })
82+ # If the user selects an index out of range, don't set no package as selected. Instead, allow for correcting the index
83+ # If the intent is to select no package, the user will be able to skip after being notified the index is out of range
84+ if ($selectedPackage ) {
85+ $packageSelected = $true
86+ } else {
87+ Write-Host ' Index out of range, please try again'
88+ }
89+ } catch {
90+ Write-Host ' Invalid entry, please try again'
91+ }
92+ }
93+ }
94+
95+ # If a package was selected, add it to the package list; Otherwise, continue
96+ if ($selectedPackage ) {
97+ $unit = @ {' resource' = ' Microsoft.WinGet.DSC/WinGetPackage' ; ' directives' = @ {' description' = $selectedPackage.Name ; ' allowPrerelease' = $true ; }; ' settings' = @ {' id' = $selectedPackage.Id ; ' source' = $selectedPackage.Source } }
98+ [void ]$finalPackages.Add ($unit )
99+ Write-Host " Added $ ( $selectedPackage.Name ) " - ForegroundColor Blue
100+ }
101+
102+ } else {
103+ Write-Host ' No package found matching input criteria.' - ForegroundColor DarkYellow
104+ }
105+ } while ($ (Read-Host ' Would you like to add another package? [y/n]' ) -eq ' y' )
106+
107+ Write-Host
108+ $fileName = Read-Host ' Name of the configuration file (without extension)'
109+ $filePath = Join-Path - Path (Get-Location ) - ChildPath " $ ( $fileName ) .winget"
110+
111+ $rawYaml = ConvertTo-Yaml @ {' properties' = @ {' resources' = $finalPackages ; ' configurationVersion' = $configurationVersion } }
112+ [System.IO.File ]::WriteAllLines($filePath , @ ($DSCHeader , ' ' , $rawYaml.trim ()), $Utf8NoBomEncoding )
113+
114+ Write-Host
115+ Write-Host ' Testing resulting file...' - ForegroundColor yellow
116+ (& winget configure -- help) > $null
117+
118+ if ($LASTEXITCODE -eq 0 ) {
119+ winget configure validate -- file $filePath
120+ } else {
121+ Write-Host " 'winget configure' is not available, skipping validation." - ForegroundColor Yellow
122+ }
123+
124+ Write-Host " Configuration file created at: $ ( $filePath ) " - ForegroundColor Green
0 commit comments