Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
e6967a2
Route generation module installs through the private CFS feed (PowerS…
gavinbarron Aug 13, 2026
e8ebc7b
Merge branch 'main' into gavinbarron/cfs-psgallery-private-feed
gavinbarron Aug 18, 2026
835ecba
fix: make Register-CfsFeed tolerate existing package source (CFSClean)
gavinbarron Aug 24, 2026
11cede3
Merge remote-tracking branch 'origin/main' into gavinbarron/cfs-psgal…
gavinbarron Aug 24, 2026
1a72352
fix: make Register-CfsFeed robust to non-terminating source collision
gavinbarron Aug 24, 2026
c7a5c92
ci: set errorActionPreference=continue on Register private module fee…
gavinbarron Aug 24, 2026
a99fe74
ci: reset stray LASTEXITCODE after Register private module feed
gavinbarron Aug 24, 2026
4143f53
fix: source locked module GUID from the private feed package (CFSClean)
gavinbarron Aug 24, 2026
e8465e5
fix: unregister public PSGallery so installs resolve only via the pri…
gavinbarron Aug 24, 2026
40aa985
ci: pre-install generation tooling modules from private feed (CFSClean)
gavinbarron Aug 25, 2026
42808b5
fix: make Get-CfsModuleGuid robust - Save-Package latest directly fro…
gavinbarron Aug 26, 2026
7b976f6
ci: pre-seed NuGet package provider to avoid PS Gallery bootstrap (CF…
gavinbarron Aug 26, 2026
305fa7f
fix: robust GUID via direct HTTP nupkg download + unregister PSGaller…
gavinbarron Aug 26, 2026
80646ff
diag: log Get-CfsModuleGuid path + map SYSTEM_ACCESSTOKEN in generati…
gavinbarron Aug 26, 2026
be86e3d
fix: delimit variable name in Get-CfsModuleGuid diagnostics
gavinbarron Aug 26, 2026
7b3b20d
fix: pre-install Az.Accounts + map SYSTEM_ACCESSTOKEN into workload/m…
gavinbarron Aug 26, 2026
81b1964
chore: remove GUID diagnostics and ineffective NuGet provider pre-seed
gavinbarron Aug 27, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .azure-pipelines/ci-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ variables:
REGISTRY: 'msgraphprodregistry.azurecr.io'
REGISTRY_NAME: 'msgraphprodregistry'
IMAGE_NAME: 'public/microsoftgraph/powershell'
# Expose the build identity's token as a process-wide env var so generation scripts (including
# ForEach-Object -Parallel runspaces) can authenticate to the private CFS module feed. (CFSClean)
SYSTEM_ACCESSTOKEN: $(System.AccessToken)

trigger:
branches:
Expand Down
3 changes: 3 additions & 0 deletions .azure-pipelines/command-metadata-refresh.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@ variables:
BuildAgent: ${{ parameters.BuildAgent }}
Branch: "ModuleCommandMetadataRefresh"
BaseBranch: ${{ parameters.BaseBranch }}
# Expose the build identity's token as a process-wide env var so generation scripts (including
# ForEach-Object -Parallel runspaces) can authenticate to the private CFS module feed. (CFSClean)
SYSTEM_ACCESSTOKEN: $(System.AccessToken)

trigger:
branches:
Expand Down
42 changes: 42 additions & 0 deletions .azure-pipelines/common-templates/install-tools.yml
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,48 @@ steps:
Copy-Item -Path $src -Destination $dst -Force
Write-Host "Copied npm config to $dst"

- task: PowerShell@2
displayName: Register private module feed (CFSClean)
inputs:
targetType: inline
pwsh: true
errorActionPreference: continue
script: |
# Register the private Azure Artifacts feed (PowerShell Gallery upstream) as a Trusted
# PSRepository so generation-time Install-Module/Find-Module resolve through it instead of
# the public PowerShell Gallery. Persisted for the job (visible to later steps + runspaces).
# errorActionPreference is 'continue' because PackageManagement emits benign non-terminating
# errors (e.g. source-already-registered) that would otherwise fail the task; Register-CfsFeed
# throws on genuine failure, which still fails the step.
. "$(Build.SourcesDirectory)/tools/Get-CfsFeedCredential.ps1"
Unregister-PublicPSGallery
Register-CfsFeed
Get-PSRepository | Format-List Name, SourceLocation, InstallationPolicy, Trusted
# PowerShellGet bootstraps the NuGet provider via a native tool during registration, which can
# leave a stray non-zero $LASTEXITCODE that fails the task even though registration succeeded.
# Register-CfsFeed throws on genuine failure (halting before this line), so reset it here.
$global:LASTEXITCODE = 0
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)

- task: PowerShell@2
displayName: Pre-install generation tooling modules (CFSClean)
inputs:
targetType: inline
pwsh: true
errorActionPreference: continue
script: |
# Install PlatyPS / Pester / powershell-yaml / PowerHTML from the private feed up-front, in this
# controlled credential context, so the lazy Install-Module calls during generation are skipped
# by their Get-Module -ListAvailable guards (authenticated private-feed installs are fragile in
# the parallel generation runspaces).
. "$(Build.SourcesDirectory)/tools/Get-CfsFeedCredential.ps1"
Install-CfsToolingModules
Get-Module -ListAvailable -Name PlatyPS, Pester, powershell-yaml, PowerHTML | Format-Table Name, Version, Path -AutoSize
$global:LASTEXITCODE = 0
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)

- task: Npm@1
displayName: Install AutoRest
retryCountOnTaskFailure: 2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ steps:
pwsh: true
script: |
. $(System.DefaultWorkingDirectory)/tools/GenerateAuthenticationModule.ps1 -EnableSigning:$${{ parameters.Sign }} -Build
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)

- ${{ if eq(parameters.Test, true) }}:
- task: PowerShell@2
Expand Down
4 changes: 3 additions & 1 deletion .azure-pipelines/generation-templates/meta-module.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

parameters:
Expand Down Expand Up @@ -50,3 +50,5 @@ steps:
pwsh: true
script: |
. $(System.DefaultWorkingDirectory)/tools/GenerateMetaModule.ps1 -Pack -ArtifactsLocation $(Build.ArtifactStagingDirectory)
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

parameters:
Expand All @@ -20,6 +20,8 @@ steps:
pwsh: true
script: |
. $(System.DefaultWorkingDirectory)/tools/GenerateModules.ps1 -EnableSigning:$${{ parameters.Sign }} -Build -ExcludeExampleTemplates -ExcludeNotesSection
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)

- template: ../common-templates/guardian-analyzer.yml

Expand Down Expand Up @@ -94,3 +96,5 @@ steps:
pwsh: true
script: |
. $(System.DefaultWorkingDirectory)/tools/GenerateModules.ps1 -SkipGeneration -Pack -ArtifactsLocation $(Build.ArtifactStagingDirectory)
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
3 changes: 3 additions & 0 deletions .azure-pipelines/weekly-generation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ parameters:
variables:
BaseBranch: ${{ parameters.BaseBranch }}
BuildAgent: ${{ parameters.BuildAgent }}
# Expose the build identity's token as a process-wide env var so generation scripts (including
# ForEach-Object -Parallel runspaces) can authenticate to the private CFS module feed. (CFSClean)
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
trigger: none
pr: none
schedules:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ BeforeAll {
$ModulePath = Join-Path $PSScriptRoot "..\artifacts\$ModuleName.psd1"
Import-Module $ModulePath -Force
$RandomClientId = (New-Guid).Guid
Install-Module Az.Accounts -Repository PSGallery -Scope CurrentUser -Force -AllowClobber
# CFSClean: Az.Accounts is pre-installed from the private feed in install-tools (public PSGallery is
# unregistered under network isolation), so only install here if it is somehow not already present.
if (-not (Get-Module -Name Az.Accounts -ListAvailable)) {
Install-Module Az.Accounts -Scope CurrentUser -Force -AllowClobber
}
}
Describe 'Connect-MgGraph ParameterSets' {
BeforeAll {
Expand Down
8 changes: 6 additions & 2 deletions tools/BuildModule.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -66,8 +66,12 @@ if ($ModuleFullName -ne "Microsoft.Graph.Authentication") {
}

# Lock module GUID. See https://github.com/Azure/autorest.powershell/issues/981.
$ExistingModule = Find-Module $ModuleFullName -Repository PSGallery -ErrorAction SilentlyContinue
$ModuleGuid = ($null -eq $ExistingModule) ? (New-Guid).Guid : $ExistingModule.AdditionalMetadata.GUID
# CFSClean: the private feed does not surface the module GUID via Find-Module's AdditionalMetadata,
# so read it from the package published on the feed. Mint a new GUID only when unpublished (matches
# the original "first publish" behaviour) without ever querying the public PowerShell Gallery.
. (Join-Path $PSScriptRoot 'Get-CfsFeedCredential.ps1')
$ModuleGuid = Get-CfsModuleGuid -Name $ModuleFullName
if ([string]::IsNullOrWhiteSpace($ModuleGuid)) { $ModuleGuid = (New-Guid).Guid }

[HashTable]$ModuleManifestSettings = @{
Guid = $ModuleGuid
Expand Down
2 changes: 1 addition & 1 deletion tools/GenerateAuthenticationModule.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
# Licensed under the MIT License.
[CmdletBinding()]
Param(
[string] $RepositoryName = "PSGallery",
[string] $RepositoryName = "PowerShell_V2_Build",
[string] $RepositoryApiKey,
[string] $ArtifactsLocation = (Join-Path $PSScriptRoot "..\artifacts\"),
[switch] $Build,
Expand Down
6 changes: 5 additions & 1 deletion tools/GenerateHelp.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,12 @@ Param(
[string] $ModuleMappingConfigPath = (Join-Path $PSScriptRoot "..\config\ModulesMapping.jsonc")
)
# Install PlatyPS
# CFSClean: install tooling modules from the private feed (PowerShell Gallery upstream).
. (Join-Path $PSScriptRoot 'Get-CfsFeedCredential.ps1')
$__cfsCred = Get-CfsFeedCredential
if ($null -ne $__cfsCred) { $PSDefaultParameterValues['Install-Module:Credential'] = $__cfsCred }
if (!(Get-Module -Name PlatyPS -ListAvailable)) {
Install-Module PlatyPS -Force
Install-Module PlatyPS -Repository (Get-CfsFeedName) -Force
}
Import-Module PlatyPS -Force -Scope Global

Expand Down
2 changes: 1 addition & 1 deletion tools/GenerateMetaModule.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ Param(
[ValidateSet("v1.0", "beta")]
$ApiVersion = @("v1.0", "beta"),
[string] $RepositoryApiKey,
[string] $RepositoryName = "PSGallery",
[string] $RepositoryName = "PowerShell_V2_Build",
[string] $ArtifactsLocation = (Join-Path $PSScriptRoot "..\artifacts\"),
[switch] $Pack,
[switch] $Publish,
Expand Down
10 changes: 9 additions & 1 deletion tools/GenerateRollUpModule.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
[CmdletBinding()]
Param(
[string] $RepositoryApiKey,
[string] $RepositoryName = "PSGallery",
[string] $RepositoryName = "PowerShell_V2_Build",
[string] $ArtifactsLocation = (Join-Path $PSScriptRoot "..\artifacts\"),
[string] $ModuleMappingConfigPath = (Join-Path $PSScriptRoot "..\config\ModulesMapping.jsonc"),
[int] $ModulePreviewNumber = -1,
Expand All @@ -19,6 +19,14 @@ enum VersionState {
}
$ErrorActionPreference = 'Stop'
$LASTEXITCODE = $null
# CFSClean: authenticate module installs/queries to the private feed (credential from the build token).
. (Join-Path $PSScriptRoot 'Get-CfsFeedCredential.ps1')
$__cfsCred = Get-CfsFeedCredential
if ($null -ne $__cfsCred) {
$PSDefaultParameterValues['Find-Module:Credential'] = $__cfsCred
$PSDefaultParameterValues['Install-Module:Credential'] = $__cfsCred
$PSDefaultParameterValues['Save-Module:Credential'] = $__cfsCred
}
if ($PSEdition -ne 'Core') {
Write-Error 'This script requires PowerShell Core to execute. [Note] Generated cmdlets will work in both PowerShell Core or Windows PowerShell.'
}
Expand Down
138 changes: 138 additions & 0 deletions tools/Get-CfsFeedCredential.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.

<#
.SYNOPSIS
Shared helpers to route PowerShell module installs/queries through the private Azure Artifacts
feed (CFSClean network isolation) instead of the public PowerShell Gallery.

.DESCRIPTION
The private feed `PowerShell_V2_Build` has a PowerShell Gallery upstream, so it can serve both
the internally published Graph modules and public tooling modules (Pester, PlatyPS,
powershell-yaml, PowerHTML). Reads the credential from the process-wide $env:SYSTEM_ACCESSTOKEN
(mapped from $(System.AccessToken) at the pipeline `variables:` level), so it works inside
ForEach-Object -Parallel runspaces where session state is not inherited.
#>

$script:CfsFeedName = 'PowerShell_V2_Build'
$script:CfsFeedUrl = 'https://microsoftgraph.pkgs.visualstudio.com/0985d294-5762-4bc2-a565-161ef349ca3e/_packaging/PowerShell_V2_Build/nuget/v2'

function Get-CfsFeedName {
return $script:CfsFeedName
}

function Get-CfsFeedCredential {
# Returns a PSCredential built from the build identity's access token, or $null when the token is
# unavailable (e.g. local dev), in which case callers fall back to their default behaviour.
if ([string]::IsNullOrWhiteSpace($env:SYSTEM_ACCESSTOKEN)) {
return $null
}
$token = ConvertTo-SecureString $env:SYSTEM_ACCESSTOKEN -AsPlainText -Force
return [System.Management.Automation.PSCredential]::new('azure', $token)
}

function Register-CfsFeed {
# Registers the private feed as a Trusted PSRepository (idempotent). Persisted under the user's
# PowerShellGet config, so a single registration per job is visible to later steps and runspaces.
$cred = Get-CfsFeedCredential
# Get-PSRepository can lazily return nothing in a fresh session even when the source is already
# persisted (registered by an earlier step/runspace). Get-PackageSource surfaces that collision,
# so check both before attempting to register.
if ((Get-PSRepository -Name $script:CfsFeedName -ErrorAction SilentlyContinue) -or
(Get-PackageSource -Name $script:CfsFeedName -ErrorAction SilentlyContinue)) {
Write-Host "Package source '$($script:CfsFeedName)' is already registered; skipping."
return
}
# The "already added" collision is a non-terminating error emitted by an internal PackageManagement
# cmdlet that bypasses -ErrorAction Stop (and would otherwise fail the task under its default Stop
# preference), so redirect every stream to null and verify the outcome instead of trusting the call.
Register-PSRepository -Name $script:CfsFeedName -SourceLocation $script:CfsFeedUrl -InstallationPolicy Trusted -Credential $cred -ErrorAction SilentlyContinue *> $null
if (-not (Get-PSRepository -Name $script:CfsFeedName -ErrorAction SilentlyContinue)) {
throw "Failed to register PSRepository '$($script:CfsFeedName)'."
}
Write-Host "Registered PSRepository '$($script:CfsFeedName)'."
}

function Unregister-PublicPSGallery {
# Remove the public PowerShell Gallery. Call this FIRST, before any other PowerShellGet operation,
# so PSGallery is gone before an enumeration resolves its source location (which egresses to
# www.powershellgallery.com - a CFSClean2 violation). Unregister-PackageSource removes the source
# entry without resolving its location; the PSRepository fallback covers the PowerShellGet view.
Unregister-PackageSource -Name 'PSGallery' -Force -ErrorAction SilentlyContinue *> $null
if (Get-PSRepository -Name 'PSGallery' -ErrorAction SilentlyContinue) {
Unregister-PSRepository -Name 'PSGallery' -ErrorAction SilentlyContinue *> $null
}
Write-Host "Removed public 'PSGallery'; module installs now resolve only through '$($script:CfsFeedName)'."
$global:LASTEXITCODE = 0
}

function Install-CfsToolingModules {
# Pre-installs the generation-time tooling modules from the private feed once, in this controlled
# credential context, so the lazy Install-Module calls during generation are skipped by their
# Get-Module -ListAvailable guards. This avoids repeating authenticated private-feed installs across
# many generation steps and parallel runspaces (where credential/source resolution is fragile).
$cred = Get-CfsFeedCredential
$tooling = @(
@{ Name = 'PlatyPS' },
@{ Name = 'Pester'; SkipPublisherCheck = $true },
@{ Name = 'powershell-yaml'; AcceptLicense = $true },
@{ Name = 'PowerHTML' },
@{ Name = 'Az.Accounts' }
)
foreach ($t in $tooling) {
if (Get-Module -Name $t.Name -ListAvailable) {
Write-Host "Tooling module '$($t.Name)' already available; skipping."
continue
}
$params = @{ Name = $t.Name; Repository = $script:CfsFeedName; Scope = 'AllUsers'; Force = $true; AllowClobber = $true }
if ($null -ne $cred) { $params.Credential = $cred }
if ($t.SkipPublisherCheck) { $params.SkipPublisherCheck = $true }
if ($t.AcceptLicense) { $params.AcceptLicense = $true }
Install-Module @params
Write-Host "Installed tooling module '$($t.Name)' from '$($script:CfsFeedName)'."
}
$global:LASTEXITCODE = 0
}

function Get-CfsModuleGuid {
# Returns the GUID of the module already published to the private feed, or $null when it is not
# published there or the GUID cannot be determined (callers then mint a fresh GUID, preserving the
# original "first publish" behaviour). The Azure Artifacts feed does not surface the GUID via
# Find-Module's AdditionalMetadata (public PS Gallery does), so this downloads the published package
# directly over HTTP from the feed's NuGet v2 OData endpoint and reads the GUID from its manifest.
# Using raw HTTP (not Find-Module/Save-Package) avoids PowerShellGet/PackageManagement source
# resolution, which is unreliable in the generation runspaces, and never touches public PS Gallery.
# The module GUID is version-independent (locked), so any published version's manifest is fine.
param(
[Parameter(Mandatory)][string] $Name
)
if ([string]::IsNullOrWhiteSpace($env:SYSTEM_ACCESSTOKEN)) { return $null }
$headers = @{ Authorization = 'Basic ' + [Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("azure:$($env:SYSTEM_ACCESSTOKEN)")) }
$tmp = Join-Path ([System.IO.Path]::GetTempPath()) ("cfsguid_" + [System.Guid]::NewGuid().ToString('N'))
try {
New-Item -ItemType Directory -Path $tmp -Force | Out-Null
$findUri = "$($script:CfsFeedUrl)/FindPackagesById()?id='$Name'"
$resp = Invoke-WebRequest -Uri $findUri -Headers $headers -UseBasicParsing -ErrorAction Stop
[xml]$xml = $resp.Content
$entry = @($xml.feed.entry) | Where-Object { $_.content.src } | Select-Object -Last 1
if ($null -eq $entry) { return $null }
$nupkgPath = Join-Path $tmp "$Name.nupkg"
Invoke-WebRequest -Uri $entry.content.src -Headers $headers -OutFile $nupkgPath -UseBasicParsing -ErrorAction Stop
Add-Type -AssemblyName System.IO.Compression.FileSystem
$zip = [System.IO.Compression.ZipFile]::OpenRead($nupkgPath)
try {
$psd1 = $zip.Entries | Where-Object { $_.Name -eq "$Name.psd1" } | Select-Object -First 1
if ($null -eq $psd1) { return $null }
$reader = [System.IO.StreamReader]::new($psd1.Open())
try { $content = $reader.ReadToEnd() } finally { $reader.Dispose() }
}
finally { $zip.Dispose() }
$match = [regex]::Match($content, "(?im)^\s*GUID\s*=\s*['`"]([0-9a-fA-F-]{36})['`"]")
if ($match.Success) { return $match.Groups[1].Value }
return $null
}
catch { return $null }
finally {
Remove-Item -Path $tmp -Recurse -Force -ErrorAction SilentlyContinue
}
}
8 changes: 6 additions & 2 deletions tools/ImportExamples.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -575,13 +575,17 @@ function Get-ExistingCorrectExamples {
}
$RetainedExamples = New-Object Collections.Generic.List[string]

# CFSClean: install tooling modules from the private feed (PowerShell Gallery upstream).
. (Join-Path $PSScriptRoot 'Get-CfsFeedCredential.ps1')
$__cfsCred = Get-CfsFeedCredential
if ($null -ne $__cfsCred) { $PSDefaultParameterValues['Install-Module:Credential'] = $__cfsCred }
if (!(Get-Module "powershell-yaml" -ListAvailable -ErrorAction SilentlyContinue)) {
Install-Module "powershell-yaml" -AcceptLicense -Scope CurrentUser -Force
Install-Module "powershell-yaml" -Repository (Get-CfsFeedName) -AcceptLicense -Scope CurrentUser -Force
}

If (-not (Get-Module -ErrorAction Ignore -ListAvailable PowerHTML)) {
Write-Verbose "Installing PowerHTML module for the current user..."
Install-Module PowerHTML -ErrorAction Stop -Scope CurrentUser -Force
Install-Module PowerHTML -Repository (Get-CfsFeedName) -ErrorAction Stop -Scope CurrentUser -Force
}
Import-Module -ErrorAction Stop PowerHTML

Expand Down
6 changes: 5 additions & 1 deletion tools/TestModule.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@ param([string] $ModulePath, [string] $ModuleName, [string] $ModuleTestsPath, [sw
$ErrorActionPreference = 'Stop'

# Install Pester
# CFSClean: install tooling modules from the private feed (PowerShell Gallery upstream).
. (Join-Path $PSScriptRoot 'Get-CfsFeedCredential.ps1')
$__cfsCred = Get-CfsFeedCredential
if ($null -ne $__cfsCred) { $PSDefaultParameterValues['Install-Module:Credential'] = $__cfsCred }
if (!(Get-Module -Name Pester -ListAvailable)) {
Install-Module -Name Pester -Force -SkipPublisherCheck
Install-Module -Name Pester -Repository (Get-CfsFeedName) -Force -SkipPublisherCheck
}

if(-not $Isolated) {
Expand Down
7 changes: 5 additions & 2 deletions tools/UpdateOpenApi.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@ if ($PSEdition -ne 'Core') {
}

if (!(Get-Module powershell-yaml -ListAvailable)) {
# Install Powershell-yaml
Install-Module powershell-yaml -Force
# Install Powershell-yaml from the private feed (PowerShell Gallery upstream). (CFSClean)
. (Join-Path $PSScriptRoot 'Get-CfsFeedCredential.ps1')
$__cfsCred = Get-CfsFeedCredential
if ($null -ne $__cfsCred) { $PSDefaultParameterValues['Install-Module:Credential'] = $__cfsCred }
Install-Module powershell-yaml -Repository (Get-CfsFeedName) -Force
}

$GraphVersion = "v1.0"
Expand Down
Loading
Loading