From a573368f9c097e69ecb24cb412627cbe0c296151 Mon Sep 17 00:00:00 2001 From: Gijs Reijn Date: Wed, 23 Oct 2024 11:57:17 +0200 Subject: [PATCH 1/2] Adding VSCodeInstaller class --- .../Microsoft.VSCode.Dsc.psd1 | 6 +- .../Microsoft.VSCode.Dsc.psm1 | 475 ++++++++++++++++-- .../Microsoft.VSCode.Dsc.Tests.ps1 | 95 ++-- 3 files changed, 485 insertions(+), 91 deletions(-) diff --git a/resources/Microsoft.VSCode.Dsc/Microsoft.VSCode.Dsc.psd1 b/resources/Microsoft.VSCode.Dsc/Microsoft.VSCode.Dsc.psd1 index b04d7a3f..a55c2172 100644 --- a/resources/Microsoft.VSCode.Dsc/Microsoft.VSCode.Dsc.psd1 +++ b/resources/Microsoft.VSCode.Dsc/Microsoft.VSCode.Dsc.psd1 @@ -8,13 +8,15 @@ Description = 'DSC Resource for Visual Studio Code' PowerShellVersion = '7.2' DscResourcesToExport = @( - 'VSCodeExtension' + 'VSCodeExtension', + 'VSCodeInstaller' ) PrivateData = @{ PSData = @{ # Tags applied to this module. These help with module discovery in online galleries. Tags = @( - 'PSDscResource_VSCodeExtension' + 'PSDscResource_VSCodeExtension', + 'PSDscResource_VSCodeInstaller' ) # Prerelease string of this module diff --git a/resources/Microsoft.VSCode.Dsc/Microsoft.VSCode.Dsc.psm1 b/resources/Microsoft.VSCode.Dsc/Microsoft.VSCode.Dsc.psm1 index 86e0e1d0..651ccdaa 100644 --- a/resources/Microsoft.VSCode.Dsc/Microsoft.VSCode.Dsc.psm1 +++ b/resources/Microsoft.VSCode.Dsc/Microsoft.VSCode.Dsc.psm1 @@ -5,7 +5,8 @@ $ErrorActionPreference = "Stop" Set-StrictMode -Version Latest #region Functions -function Get-VSCodeCLIPath { +function Get-VSCodeCLIPath +{ param ( [switch]$Insiders ) @@ -28,13 +29,21 @@ function Get-VSCodeCLIPath { $insidersUserInstallLocation = TryGetRegistryValue -Key "$($userUninstallRegistry)\$($vsCodeInsidersUserProductCode)" -Property $installLocationProperty if ($insidersUserInstallLocation) { - return $insidersUserInstallLocation + $cmdPath + return @{ + Path = $insidersUserInstallLocation + $cmdPath + Version = (Get-Item -Path (Join-Path $insidersUserInstallLocation 'Code - Insiders.exe')).VersionInfo.ProductVersion + Insiders = $true + } } $insidersMachineInstallLocation = TryGetRegistryValue -Key "$($machineUninstallRegistry)\$($vsCodeInsidersMachineProductCode)" -Property $installLocationProperty if ($insidersMachineInstallLocation) { - return $insidersMachineInstallLocation + $cmdPath + return @{ + Path = $insidersMachineInstallLocation + $cmdPath + Version = (Get-Item -Path (Join-Path $insidersMachineInstallLocation 'Code - Insiders.exe')).VersionInfo.ProductVersion + Insiders = $true + } } } else @@ -43,20 +52,51 @@ function Get-VSCodeCLIPath { $codeUserInstallLocation = TryGetRegistryValue -Key "$($userUninstallRegistry)\$($vsCodeUserProductCode)" -Property $installLocationProperty if ($codeUserInstallLocation) { - return $codeUserInstallLocation + $cmdPath + return @{ + Path = $codeUserInstallLocation + $cmdPath + Version = (Get-Item -Path (Join-Path $codeUserInstallLocation 'Code.exe')).VersionInfo.ProductVersion + } } $codeMachineInstallLocation = TryGetRegistryValue -Key "$($machineUninstallRegistry)\$($vsCodeMachineProductCode)" -Property $installLocationProperty if ($codeMachineInstallLocation) { - return $codeMachineInstallLocation + $cmdPath + return @{ + Path = $codeMachineInstallLocation + $cmdPath + Version = (Get-Item -Path (Join-Path $codeMachineInstallLocation 'Code.exe')).VersionInfo.ProductVersion + } } } - throw "VSCode is not installed." + return @{ + Path = $null + Version = $null + } +} + +function Test-VSCodeCLIPath +{ + param ( + [switch]$Insiders, + [string]$Version + ) + + $vsCodeCLIPath = Get-VSCodeCLIPath -Insiders:$Insiders + if ($null -eq $vsCodeCLIPath.Path) + { + return $false + } + + if ($Version -and $vsCodeCLIPath.Version -ne $Version) + { + return $false + } + + return $true } -function Install-VSCodeExtension { +function Install-VSCodeExtension +{ [CmdletBinding()] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] @@ -65,11 +105,14 @@ function Install-VSCodeExtension { [string]$Version ) - begin { - function Get-VSCodeExtensionInstallArgument { + begin + { + function Get-VSCodeExtensionInstallArgument + { param([string]$Name, [string]$Version) - if ([string]::IsNullOrEmpty($Version)) { + if ([string]::IsNullOrEmpty($Version)) + { return $Name } @@ -80,13 +123,15 @@ function Install-VSCodeExtension { } } - process { + process + { $installArgument = Get-VSCodeExtensionInstallArgument @PSBoundParameters Invoke-VSCode -Command "--install-extension $installArgument" } } -function Uninstall-VSCodeExtension { +function Uninstall-VSCodeExtension +{ [CmdletBinding()] param ( [Parameter(Mandatory, ValueFromPipelineByPropertyName)] @@ -96,28 +141,32 @@ function Uninstall-VSCodeExtension { Invoke-VSCode -Command "--uninstall-extension $($this.Name)" } -function Invoke-VSCode { +function Invoke-VSCode +{ param ( [Parameter(Mandatory = $true)] [string]$Command ) - try { + try + { Invoke-Expression "& `"$VSCodeCLIPath`" $Command" } - catch { + catch + { throw ("Executing {0} with {$Command} failed." -f $VSCodeCLIPath) } } -function TryGetRegistryValue{ +function TryGetRegistryValue +{ param ( [Parameter(Mandatory = $true)] [string]$Key, [Parameter(Mandatory = $true)] [string]$Property - ) + ) if (Test-Path -Path $Key) { @@ -135,11 +184,327 @@ function TryGetRegistryValue{ Write-Verbose "Registry key does not exist." } } + +function Save-WithBitsTransfer { + param( + [Parameter(Mandatory=$true)] + [string] + $FileUri, + + [Parameter(Mandatory=$true)] + [string] + $Destination, + + [Parameter(Mandatory=$true)] + [string] + $AppName + ) + + Remove-Item -Force $Destination -ErrorAction SilentlyContinue + + $bitsDl = Start-BitsTransfer $FileUri -Destination $Destination -Asynchronous + + while (($bitsDL.JobState -eq 'Transferring') -or ($bitsDL.JobState -eq 'Connecting')) { + Write-Verbose -Message ("Downloading: $AppName. Status: {0}. PercentComplete: {1}" -f ("$([math]::round($bitsDl.BytesTransferred / 1mb))mb / $([math]::round($bitsDl.BytesTotal / 1mb))mb"), (($($bitsDl.BytesTransferred) / $($bitsDl.BytesTotal) * 100 )) ) + } + + switch ($bitsDl.JobState) { + + 'Transferred' { + Complete-BitsTransfer -BitsJob $bitsDl + break + } + + 'Error' { + throw 'Error downloading installation media.' + } + } +} + +function Get-CodePlatformInformation +{ + param ( + [Parameter(Mandatory = $false)] + [AllowNull()] + [string] $Version, + + [Parameter(Mandatory = $false)] + [switch] $Insiders + ) + + if ($IsWindows -or $PSVersionTable.PSVersion.Major -lt 6) { + $os = 'Windows' + } + elseif ($IsLinux) { + $os = 'Linux' + } + elseif ($IsMacOS) { + $os = 'MacOS' + } + else { + throw 'Could not identify operating system' + } + + switch ($os) { + 'Linux' { + # TODO: Add support for Linux + } + + 'MacOS' { + # TODO: Add support for MacOS + } + + 'Windows' { + $ext = 'exe' + if ($Insiders) + { + # TODO: insiders does not have a direct URL, need to get the URL from the API + $url = (Invoke-RestMethod -Uri 'https://update.code.visualstudio.com/api/update/win32-x64/insider/0000000000000000000000000000000000000000').url + $dest = Join-Path $env:TEMP "VSCodeSetup-Insiders.$ext" + } + else + { + # TODO: might figure out a way to do user and system installations + # info on URLs: https://code.visualstudio.com/docs/supporting/faq#_previous-release-versions + if ($Version) + { + $url = "https://update.code.visualstudio.com/$Version/win32-x64/stable" + $dest = Join-Path $env:TEMP "VSCodeSetup.$version.$ext" + } + else + { + $url = 'https://update.code.visualstudio.com/latest/win32-x64/stable' + $dest = Join-Path $env:TEMP "VSCodeSetup.$ext" + } + } + } + } + + return @{ + FileUri = $url + Version = $Version + Extension = $ext + OS = $os + Destination = $dest + } +} + +function Install-VSCode { + param ( + [Parameter(Mandatory = $false)] + [AllowNull()] + [string] $Version, + + [Parameter(Mandatory = $false)] + [switch] $Insiders + ) + + $platformInfo = Get-CodePlatformInformation -Version $Version -Insiders:$Insiders + + if (-not (Test-VSCodeCLIPath @PSBoundParameters)) + { + if ($platformInfo.OS -eq 'Windows') { + try { + $appName = 'Visual Studio Code' + Save-WithBitsTransfer -FileUri $platformInfo.FileUri -Destination $platformInfo.Destination -AppName $appName + + $exeArgs = '/verysilent /tasks=addtopath' + $process = Start-Process -FilePath $platformInfo.Destination -ArgumentList $exeArgs -Wait + } + catch + { + Throw "Failed to install Visual Studio Code. $_" + } + finally + { + if ($process) + { + Remove-Item -Path $platformInfo.Destination -Force + } + } + } + elseif ($platformInfo.OS -eq 'Linux') + { + # TODO: Add support for Linux + } + elseif ($platformInfo.OS -eq 'MacOS') + { + # TODO: Add support for MacOS + } + } + +} #endregion Functions #region DSCResources +<# +.SYNOPSIS + The `VSCodeInstaller` DSC Resource allows you to install, update, and remove Visual Studio Code. This resource ensures that the specified version of Visual Studio Code is in the desired state. + +.PARAMETER Path + The path where Visual Studio Code is installed. This is a key property not to be set. + +.PARAMETER Version + The version of Visual Studio Code to install. If not specified, the latest version will be installed. + +.PARAMETER Insiders + Indicates whether to install the Insiders version of Visual Studio Code. The default value is `$false`. + +.PARAMETER Exist + Indicates whether Visual Studio Code should exist. The default value is `$true`. + +.EXAMPLE + PS C:\> Invoke-DscResource -Name VSCodeInstaller -Method Set -Property @{} -ModuleName Microsoft.VSCode.Dsc + + # This installs the latest stable version of Visual Studio Code + +.EXAMPLE + PS C:\> $params = @{ + Version = '1.56.2' + } + PS C:\> Invoke-DscResource -Name VSCodeInstaller -Method Set -Property $params -ModuleName Microsoft.VSCode.Dsc + + # This installs a specific version of Visual Studio Code + +.EXAMPLE + PS C:\> $params = @{ + Insiders = $true + } + PS C:\> Invoke-DscResource -Name VSCodeInstaller -Method Set -Property $params -ModuleName Microsoft.VSCode.Dsc + + # This installs the latest Insiders version of Visual Studio Code + +.EXAMPLE + PS C:\> $params = @{ + Exist = $false + } + PS C:\> Invoke-DscResource -Name VSCodeInstaller -Method Set -Property $params -ModuleName Microsoft.VSCode.Dsc + + # This removes Visual Studio Code +#> [DSCResource()] -class VSCodeExtension { +class VSCodeInstaller +{ + [DscProperty(Key)] + [string] $Path + + [DscProperty()] + [string] $Version + + [DscProperty()] + [bool] $Insiders = $false + + [DscProperty()] + [bool] $Exist = $true + + [void] Set() + { + if ($this.Test()) + { + return + } + + Install-VSCode -Insiders:$this.Insiders -Version $this.Version + } + + [bool] Test() + { + $currentState = $this.Get() + if ($currentState.Exist -ne $this.Exist) + { + return $false + } + + if ($this.Version -and $this.Version -ne $currentState.Version -or $currentState.Insiders -ne $this.Insiders) + { + return $false + } + + return $true + } + + [VSCodeInstaller] Get() + { + $currentState = Get-VSCodeCLIPath -Insiders:$this.Insiders + + if ($null -ne $currentState.Path) + { + if ($this.Version -and $this.Version -ne $currentState.Version) + { + return @{ + Path = $currentState.Path + Version = $this.Version + Insiders = $this.Insiders + Exist = $false + } + } + + return $currentState + } + + return @{ + Path = $this.Path + Version = $this.Version + Insiders = $this.Insiders + Exist = $false + } + } +} +<# +.SYNOPSIS + The `VSCodeExtension` DSC Resource allows you to install, update, and remove Visual Studio Code extensions. This resource ensures that the specified Visual Studio Code extension is in the desired state. + +.PARAMETER Name + The name of the Visual Studio Code extension to manage. This is a required parameter. + +.PARAMETER Version + The version of the Visual Studio Code extension to install. If not specified, the latest version will be installed. + +.PARAMETER Exist + Indicates whether the extension should exist. The default value is `$true`. + +.PARAMETER Insiders + Indicates whether to manage the extension for the Insiders version of Visual Studio Code. The default value is `$false`. + +.EXAMPLE + PS C:\> $params = @{ + Name = 'ms-python.python' + } + PS C:\> Invoke-DscResource -Name VSCodeExtension -Method Set -Property $params -ModuleName Microsoft.VSCode.Dsc + + This installs the latest version of the Visual Studio Code extension 'ms-python.python' + +.EXAMPLE + # Install a specific version of the Visual Studio Code extension 'ms-python.python' + PS C:\> $params = @{ + Name = 'ms-python.python' + Version = '2021.5.842923320' + } + PS C:\> Invoke-DscResource -Name VSCodeExtension -Method Set -Property $params -ModuleName Microsoft.VSCode.Dsc + + This installs a specific version of the Visual Studio Code extension 'ms-python.python' + +.EXAMPLE + PS C:\> $params = @{ + Name = 'ms-python.python' + Exist = $false + } + PS C:\> Invoke-DscResource -Name VSCodeExtension -Method Set -Property $params -ModuleName Microsoft.VSCode.Dsc + + This removes the Visual Studio Code extension 'ms-python.python' + +.EXAMPLE + PS C:\> $params = @{ + Name = 'ms-python.python' + Insiders = $true + } + PS C:\> Invoke-DscResource -Name VSCodeExtension -Method Set -Property $params -ModuleName Microsoft.VSCode.Dsc + + This installs the latest version of the Visual Studio Code extension 'ms-python.python' for the Insiders version of Visual Studio Code +#> +[DSCResource()] +class VSCodeExtension +{ [DscProperty(Key)] [string] $Name @@ -154,21 +519,25 @@ class VSCodeExtension { static [hashtable] $InstalledExtensions - VSCodeExtension() { + VSCodeExtension() + { } - VSCodeExtension([string]$Name, [string]$Version) { + VSCodeExtension([string]$Name, [string]$Version) + { $this.Name = $Name $this.Version = $Version } [VSCodeExtension[]] Export([bool]$Insiders) { - if ($Insiders) { - $script:VSCodeCLIPath = Get-VSCodeCLIPath -Insiders + if ($Insiders) + { + $script:VSCodeCLIPath = (Get-VSCodeCLIPath -Insiders).Path } - else { - $script:VSCodeCLIPath = Get-VSCodeCLIPath + else + { + $script:VSCodeCLIPath = (Get-VSCodeCLIPath).Path } $extensionList = (Invoke-VSCode -Command "--list-extensions --show-versions") -Split [Environment]::NewLine @@ -184,61 +553,74 @@ class VSCodeExtension { return $results } - [VSCodeExtension] Get() { + [VSCodeExtension] Get() + { [VSCodeExtension]::GetInstalledExtensions($this.Insiders) $currentState = [VSCodeExtension]::InstalledExtensions[$this.Name] - if ($null -ne $currentState) { + if ($null -ne $currentState) + { return [VSCodeExtension]::InstalledExtensions[$this.Name] } return [VSCodeExtension]@{ - Name = $this.Name - Version = $this.Version - Exist = $false + Name = $this.Name + Version = $this.Version + Exist = $false Insiders = $this.Insiders } } - [bool] Test() { + [bool] Test() + { $currentState = $this.Get() - if ($currentState.Exist -ne $this.Exist) { + if ($currentState.Exist -ne $this.Exist) + { return $false } - if ($null -ne $this.Version -and $this.Version -ne $currentState.Version) { + if ($null -ne $this.Version -and $this.Version -ne $currentState.Version) + { return $false } return $true } - [void] Set() { - if ($this.Test()) { + [void] Set() + { + if ($this.Test()) + { return } - if ($this.Exist) { + if ($this.Exist) + { $this.Install($false) } - else { + else + { $this.Uninstall($false) } } -#region VSCodeExtension helper functions - static [void] GetInstalledExtensions([bool]$Insiders) { + #region VSCodeExtension helper functions + static [void] GetInstalledExtensions([bool]$Insiders) + { [VSCodeExtension]::InstalledExtensions = @{} $extension = [VSCodeExtension]::new() - foreach ($extension in $extension.Export($Insiders)) { + foreach ($extension in $extension.Export($Insiders)) + { [VSCodeExtension]::InstalledExtensions[$extension.Name] = $extension } } - [void] Install([bool] $preTest) { - if ($preTest -and $this.Test()) { + [void] Install([bool] $preTest) + { + if ($preTest -and $this.Test()) + { return } @@ -246,18 +628,21 @@ class VSCodeExtension { [VSCodeExtension]::GetInstalledExtensions($this.Insiders) } - [void] Install() { + [void] Install() + { $this.Install($true) } - [void] Uninstall([bool] $preTest) { + [void] Uninstall([bool] $preTest) + { Uninstall-VSCodeExtension -Name $this.Name [VSCodeExtension]::GetInstalledExtensions($this.Insiders) } - [void] Uninstall() { + [void] Uninstall() + { $this.Uninstall($true) } -#endregion VSCodeExtension helper functions + #endregion VSCodeExtension helper functions } #endregion DSCResources diff --git a/tests/Microsoft.VSCode.Dsc/Microsoft.VSCode.Dsc.Tests.ps1 b/tests/Microsoft.VSCode.Dsc/Microsoft.VSCode.Dsc.Tests.ps1 index 7291d432..c3b1d3ff 100644 --- a/tests/Microsoft.VSCode.Dsc/Microsoft.VSCode.Dsc.Tests.ps1 +++ b/tests/Microsoft.VSCode.Dsc/Microsoft.VSCode.Dsc.Tests.ps1 @@ -13,42 +13,46 @@ Set-StrictMode -Version Latest BeforeAll { Install-Module -Name PSDesiredStateConfiguration -Force -SkipPublisherCheck Import-Module Microsoft.VSCode.Dsc - - # Install VSCode - Invoke-WebRequest https://raw.githubusercontent.com/PowerShell/vscode-powershell/main/scripts/Install-VSCode.ps1 -UseBasicParsing -OutFile Install-VSCode.ps1 - .\Install-VSCode.ps1 -BuildEdition Stable-User -Confirm:$false - - # Install VSCode Insiders - .\Install-VSCode.ps1 -BuildEdition Insider-User -Confirm:$false } Describe 'List available DSC resources' { It 'Shows DSC Resources' { - $expectedDSCResources = "VSCodeExtension" + $expectedDSCResources = "VSCodeExtension", "VSCodeInstaller" $availableDSCResources = (Get-DscResource -Module Microsoft.VSCode.Dsc).Name - $availableDSCResources.count | Should -Be 1 + $availableDSCResources.count | Should -Be 2 $availableDSCResources | Where-Object { $expectedDSCResources -notcontains $_ } | Should -BeNullOrEmpty -ErrorAction Stop } } -Describe 'VSCodeExtension' { - It 'Keeps current extension.' -Skip:(!$IsWindows) { +Describe 'VSCodeInstaller' { + It 'Installs Visual Studio Code Insiders successfully.' -Skip:(!$IsWindows) { $parameters = @{ - Name = 'ms-vscode.powershell' + Insiders = $true } - $initialState = Invoke-DscResource -Name VSCodeExtension -ModuleName Microsoft.VSCode.Dsc -Method Get -Property $parameters - - $testResult = Invoke-DscResource -Name VSCodeExtension -ModuleName Microsoft.VSCode.Dsc -Method Test -Property $parameters - $testResult.InDesiredState | Should -Be $true - - # Invoking set should not change these values. - Invoke-DscResource -Name VSCodeExtension -ModuleName Microsoft.VSCode.Dsc -Method Set -Property $parameters - $finalState = Invoke-DscResource -Name VSCodeExtension -ModuleName Microsoft.VSCode.Dsc -Method Get -Property $parameters - $finalState.Name | Should -Be $initialState.Name - $finalState.Version | Should -Be $initialState.Version - $finalState.Exist | Should -Be $initialState.Exist + + Invoke-DscResource -Name VSCodeInstaller -ModuleName Microsoft.VSCode.Dsc -Method Set -Property $parameters + + $finalState = Invoke-DscResource -Name VSCodeInstaller -ModuleName Microsoft.VSCode.Dsc -Method Get -Property $parameters + $finalState.Path | Should -NotBeNullOrEmpty + $finalState.Exist | Should -BeTrue + $finalState.Insiders | Should -BeTrue } + It 'Installs Visual Studio Code with version successfully.' -Skip:(!$IsWindows) { + $parameters = @{ + Version = '1.94.1' + } + + Invoke-DscResource -Name VSCodeInstaller -ModuleName Microsoft.VSCode.Dsc -Method Set -Property $parameters + + $finalState = Invoke-DscResource -Name VSCodeInstaller -ModuleName Microsoft.VSCode.Dsc -Method Get -Property $parameters + $finalState.Path | Should -NotBeNullOrEmpty + $finalState.Exist | Should -BeTrue + $finalState.Version | Should -Be $parameters.Version + } +} + +Describe 'VSCodeExtension' { It 'Sets desired extension' -Skip:(!$IsWindows) { $desiredState = @{ Name = 'ms-azure-devops.azure-pipelines' @@ -63,25 +67,6 @@ Describe 'VSCodeExtension' { } Describe 'VSCodeExtension-Insiders' { - It 'Keeps current extension in Insiders edition.' -Skip:(!$IsWindows) { - $parameters = @{ - Name = 'ms-vscode.powershell' - Insiders = $true - } - - $initialState = Invoke-DscResource -Name VSCodeExtension -ModuleName Microsoft.VSCode.Dsc -Method Get -Property $parameters - - $testResult = Invoke-DscResource -Name VSCodeExtension -ModuleName Microsoft.VSCode.Dsc -Method Test -Property $parameters - $testResult.InDesiredState | Should -Be $true - - # Invoking set should not change these values. - Invoke-DscResource -Name VSCodeExtension -ModuleName Microsoft.VSCode.Dsc -Method Set -Property $parameters - $finalState = Invoke-DscResource -Name VSCodeExtension -ModuleName Microsoft.VSCode.Dsc -Method Get -Property $parameters - $finalState.Name | Should -Be $initialState.Name - $finalState.Version | Should -Be $initialState.Version - $finalState.Exist | Should -Be $initialState.Exist - } - It 'Sets desired extension in Insiders edition' -Skip:(!$IsWindows) { $desiredState = @{ Name = 'ms-azure-devops.azure-pipelines' @@ -96,6 +81,28 @@ Describe 'VSCodeExtension-Insiders' { } } -AfterAll { - # Uninstall VSCode? +Describe "VSCodeInstaller" { + # It 'Uninstalls Visual Studio Code successfully.' -Skip:(!$IsWindows) { + # $parameters = @{ + # Exist = $false + # } + + # Invoke-DscResource -Name VSCodeInstaller -ModuleName Microsoft.VSCode.Dsc -Method Set -Property $parameters + + # $finalState = Invoke-DscResource -Name VSCodeInstaller -ModuleName Microsoft.VSCode.Dsc -Method Get -Property $parameters + # $finalState.Path | Should -BeNullOrEmpty + # $finalState.Exist | Should -BeFalse + # } + + # It 'Uninstalls Visual Studio Code Insiders successfully.' -Skip:(!$IsWindows) { + # $parameters = @{ + # Exist = $false + # } + + # Invoke-DscResource -Name VSCodeInstaller -ModuleName Microsoft.VSCode.Dsc -Method Set -Property $parameters + + # $finalState = Invoke-DscResource -Name VSCodeInstaller -ModuleName Microsoft.VSCode.Dsc -Method Get -Property $parameters + # $finalState.Path | Should -BeNullOrEmpty + # $finalState.Exist | Should -BeFalse + # } } \ No newline at end of file From 2d2502902b226693af9256ba5626671dcfba5a7f Mon Sep 17 00:00:00 2001 From: Gijs Reijn Date: Wed, 23 Oct 2024 13:56:28 +0200 Subject: [PATCH 2/2] DscResource examples --- .../InstallVSCodeInsiders.dsc.document.yaml | 28 ++++++++++ .../InstallVSCodeInsiders.ps1 | 12 ++++ ...InstallVSCodeInsiders.winget.document.yaml | 16 ++++++ .../DscResources/README.md | 55 +++++++++++++++++++ 4 files changed, 111 insertions(+) create mode 100644 doc/sampleConfigurations/DscResources/Microsoft.VSCode.Dsc/InstallVSCodeInsiders.dsc.document.yaml create mode 100644 doc/sampleConfigurations/DscResources/Microsoft.VSCode.Dsc/InstallVSCodeInsiders.ps1 create mode 100644 doc/sampleConfigurations/DscResources/Microsoft.VSCode.Dsc/InstallVSCodeInsiders.winget.document.yaml create mode 100644 doc/sampleConfigurations/DscResources/README.md diff --git a/doc/sampleConfigurations/DscResources/Microsoft.VSCode.Dsc/InstallVSCodeInsiders.dsc.document.yaml b/doc/sampleConfigurations/DscResources/Microsoft.VSCode.Dsc/InstallVSCodeInsiders.dsc.document.yaml new file mode 100644 index 00000000..9b03684d --- /dev/null +++ b/doc/sampleConfigurations/DscResources/Microsoft.VSCode.Dsc/InstallVSCodeInsiders.dsc.document.yaml @@ -0,0 +1,28 @@ +# $schema=https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/config/document.json + +######################################################################################## +# This configuration will install Visual Studio Code Insiders. # +# PowerShell module: Microsoft.Dotnet.Dsc (v0.1.1-alpha) # +# NOTE: Only Windows is supported. # +######################################################################################## + +$schema: https://raw.githubusercontent.com/PowerShell/DSC/main/schemas/2024/04/config/document.json +metadata: + Microsoft.DSC: + requiredSecurityContext: Elevated # Required to install software from stable-system +resources: + resources: + - name: IsWindows + type: Microsoft/OSInfo + properties: + family: Windows + - name: Use class PowerShell resources + type: Microsoft.DSC/PowerShell + properties: + resources: + - name: Visual Studio Code Insiders + type: Microsoft.VSCode.Dsc/VSCodeInstaller + properties: + Insiders: true + dependsOn: + - "[resourceId('Microsoft.DSC/Assertion','IsWindows')]" \ No newline at end of file diff --git a/doc/sampleConfigurations/DscResources/Microsoft.VSCode.Dsc/InstallVSCodeInsiders.ps1 b/doc/sampleConfigurations/DscResources/Microsoft.VSCode.Dsc/InstallVSCodeInsiders.ps1 new file mode 100644 index 00000000..274ce7c6 --- /dev/null +++ b/doc/sampleConfigurations/DscResources/Microsoft.VSCode.Dsc/InstallVSCodeInsiders.ps1 @@ -0,0 +1,12 @@ +configuration InstallVSCodeInsiders +{ + Import-DscResource -ModuleName 'Microsoft.VSCode.Dsc' + + Node localhost + { + VSCodeInsiders InstallVSCodeInsiders + { + Insiders = $true + } + } +} \ No newline at end of file diff --git a/doc/sampleConfigurations/DscResources/Microsoft.VSCode.Dsc/InstallVSCodeInsiders.winget.document.yaml b/doc/sampleConfigurations/DscResources/Microsoft.VSCode.Dsc/InstallVSCodeInsiders.winget.document.yaml new file mode 100644 index 00000000..27ec2419 --- /dev/null +++ b/doc/sampleConfigurations/DscResources/Microsoft.VSCode.Dsc/InstallVSCodeInsiders.winget.document.yaml @@ -0,0 +1,16 @@ +# yaml-language-server: $schema=https://aka.ms/configuration-dsc-schema/0.2 + +######################################################################################## +# This configuration will install Visual Studio Code Insiders. # +# PowerShell module: Microsoft.Dotnet.Dsc (v0.1.1-alpha) # +######################################################################################## + +properties: + resources: + - resource: Microsoft.VSCode.Dsc/VSCodeInstaller + directives: + description: Install Visual Studio Code Insiders + allowPrerelease: true + settings: + Insiders: true + configurationVersion: 0.2.0 \ No newline at end of file diff --git a/doc/sampleConfigurations/DscResources/README.md b/doc/sampleConfigurations/DscResources/README.md new file mode 100644 index 00000000..fca8f228 --- /dev/null +++ b/doc/sampleConfigurations/DscResources/README.md @@ -0,0 +1,55 @@ +# Sample configurations for specific DSC resources + +The sample configurations provided in this directory showcase how to create configuration documents both for DSC and WinGet. It's up to you to decide which tool you want. To use DSC, follow the prerequisites. WinGet is included in: + +- Windows 10 Version 1809 and later +- Windows 11 + +Earlier versions of Windows 10 can use the Microsoft Store to download the App Installer package. + +## Prerequisites + +- [Desired State Configuration - v3.0.0-preview.10+](https://github.com/PowerShell/DSC/tags) +- [PSDesiredStateConfiguration - v2.0.7](https://www.powershellgallery.com/packages/PSDesiredStateConfiguration/2.0.7) + +## Getting started + +To test out each sample configuration, you only need a PowerShell terminal session. In the sample name, you should find the relevant tool belonging to which tool. To illustrate, see the following example: + +```powershell +# Use WinGet +winget configure --file InstallVSCodeInsiders.winget.document.yaml # Use --accept-configuration-agreements to ignore prompt messages + +# Use `dsc.exe` +dsc config set --path InstallVSCodeInsiders.winget.document.yaml + +# Use PSDesiredStateConfiguration +Start-DscConfiguration -Path InstallVSCodeInsider.ps1 -Force +``` + +If you don't want to use a _configuration document_, you can always invoke it using `Invoke-DscResource` command. If you inspect the module file, move examples will be found how to use it with the `Invoke-DscResource` command. + +## Resources + +### GitDsc + +### Microsoft.DotNet.Dsc + +### Microsoft.VSCode.Dsc + +Supports multiple resources to install and work with Visual Studio Code. The following resources can be used: + +- **VSCodeExtension:** DSC resource allowing you to install, update, and remove Visual Studio Code extensions. This resource ensures that the specified Visual Studio Code extension is in the desired state. +- **VSCodeInstaller:** DSC resource allowing you to install, update, and remove Visual Studio Code. This resource ensures that the specified version of Visual Studio Code is in the desired state. + +## Microsoft.Windows.Developer + +### Microsoft.Windows.Setting.Accessibility + +### Microsoft.WindowsSandbox.DSC + +### NpmDsc + +### PythonPip3Dsc + +### YarnDsc \ No newline at end of file