Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# Changelog

## 2.1.1

### Fixed

- `Invoke-MgxRequest` threw `FileNotFoundException` for `System.IO.Pipelines, Version=10.0.0.0` on hosts whose PowerShell 7.6 payload does not carry that assembly, such as the Azure DevOps `windows-2025-g2` image and Microsoft's Linux container images, which unpack PowerShell over a separately installed .NET runtime.

## 2.1.0

Merges upstream `gromedev/mgx` 2.1.1. The module name, version line, target framework and CI remain this fork's.
Expand Down
2 changes: 1 addition & 1 deletion Directory.Build.props
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project>

<PropertyGroup>
<Version>2.1.0</Version>
<Version>2.1.1</Version>
<Authors>Thomas Maillo Grome, Fabien Tschanz</Authors>
<Company>Mgx</Company>
<Copyright>(c) 2026 Thomas Maillo Grome, (c) 2026 Fabien Tschanz. All rights reserved.</Copyright>
Expand Down
5 changes: 4 additions & 1 deletion Modules/M365DSC.mgx/M365DSC.mgx.psd1
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@{
RootModule = 'M365DSC.mgx.psm1'
ModuleVersion = '2.1.0'
ModuleVersion = '2.1.1'
GUID = 'f978315f-75c0-48f5-b929-ca7a7757d1d2'
Author = 'Thomas Maillo Grome, Fabien Tschanz'
CompanyName = 'Mgx'
Expand Down Expand Up @@ -49,6 +49,9 @@
LicenseUri = 'https://github.com/Microsoft365DSC/mgx/blob/main/LICENSE'
ProjectUri = 'https://github.com/Microsoft365DSC/mgx'
ReleaseNotes = @'
v2.1.1
- Fixed Invoke-MgxRequest failing with a missing System.IO.Pipelines assembly on PowerShell 7.6 hosts that do not ship it.

v2.1.0
- Added Get-MgxContent, downloading file and media content whole or by byte range.
- Added adaptive request pacing, on by default, spacing requests per workload ahead of the token bucket. Opt out with Set-MgxOption -NoAdaptivePacing.
Expand Down
10 changes: 2 additions & 8 deletions build.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ dotnet build "$PSScriptRoot/Mgx.slnx" -c $Configuration --nologo
if ($LASTEXITCODE -ne 0) { throw "Build failed with exit code $LASTEXITCODE" }

# Copy Cmdlets + Engine DLLs (load in default ALC)
# Detect TFM from csproj instead of hardcoding (survives TFM upgrades)
$csproj = [xml](Get-Content "$PSScriptRoot/src/Mgx.Cmdlets/Mgx.Cmdlets.csproj")
$tfm = @($csproj.Project.PropertyGroup.TargetFramework | Where-Object { $_ }) | Select-Object -First 1
$CmdletsOutput = Join-Path $PSScriptRoot "src/Mgx.Cmdlets/bin/$Configuration/$tfm"
Expand All @@ -50,7 +49,6 @@ Copy-Item "$CmdletsOutput/Mgx.Cmdlets.pdb" $ModuleRoot -Force -ErrorAction Silen
Copy-Item "$CmdletsOutput/Mgx.Engine.dll" $ModuleRoot -Force
Copy-Item "$CmdletsOutput/Mgx.Engine.pdb" $ModuleRoot -Force -ErrorAction SilentlyContinue

# Copy deps.json (useful for diagnostic tooling; deleted by clean step above)
$depsJson = Join-Path $CmdletsOutput 'Mgx.Cmdlets.deps.json'
if (Test-Path $depsJson) {
Copy-Item $depsJson $ModuleRoot -Force
Expand All @@ -59,16 +57,13 @@ if (Test-Path $depsJson) {
}

# Copy third-party dependencies into Dependencies/ (loaded via ALC Resolving handler on first use)
# Polly.Core and System.Threading.RateLimiting are not in the module root;
# Mgx.Engine is NOT here - it is loaded via RequiredAssemblies in M365DSC.mgx.psd1 (see comment there).
New-Item $DepsDir -ItemType Directory -Force | Out-Null

# Copy dependency DLLs that need ALC isolation (Polly, RateLimiting)
# After D1+D2: replaced Microsoft.Extensions.Http.Resilience with direct Polly.Core 8.6.6
# This eliminated 28 transitive dependencies (51 total down to 23 packages)
$DepsToIsolate = @(
'Polly.Core.dll'
'System.Threading.RateLimiting.dll'
'System.IO.Pipelines.dll'
)

foreach ($dep in $DepsToIsolate) {
Expand All @@ -82,7 +77,7 @@ foreach ($dep in $DepsToIsolate) {

# Verify module output is in expected state
$RequiredRoot = @('Mgx.Cmdlets.dll', 'Mgx.Engine.dll', 'M365DSC.mgx.psd1', 'M365DSC.mgx.psm1')
$RequiredDeps = @('Polly.Core.dll', 'System.Threading.RateLimiting.dll')
$RequiredDeps = @('Polly.Core.dll', 'System.Threading.RateLimiting.dll', 'System.IO.Pipelines.dll')

foreach ($f in $RequiredRoot) {
if (-not (Test-Path (Join-Path $ModuleRoot $f))) {
Expand All @@ -103,7 +98,6 @@ if ($orphans) {
$helpSource = Join-Path $ModuleRoot 'help'
$helpOutput = Join-Path $ModuleRoot 'en-US'
if (Test-Path $helpSource) {
# -ListAvailable only searches PSModulePath, so check for an already-imported platyPS too
if ((Get-Module platyPS) -or (Get-Module -ListAvailable platyPS)) {
if (-not (Get-Module platyPS)) { Import-Module platyPS -ErrorAction Stop }
New-ExternalHelp -Path $helpSource -OutputPath $helpOutput -Force | Out-Null
Expand Down
10 changes: 9 additions & 1 deletion src/Mgx.Cmdlets/Mgx.Cmdlets.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<Nullable>enable</Nullable>
<RootNamespace>Mgx.Cmdlets</RootNamespace>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<RestoreEnablePackagePruning>false</RestoreEnablePackagePruning>
<!-- See Mgx.Engine.csproj: CA1416 keeps Windows-only directory APIs out of the
cross-platform code paths at build time rather than at a customer's runtime. -->
<WarningsAsErrors>$(WarningsAsErrors);CA1416</WarningsAsErrors>
Expand All @@ -18,15 +19,21 @@

<ItemGroup>
<PackageReference Include="System.Management.Automation" Version="7.6.4" PrivateAssets="all" />
<PackageReference Include="System.IO.Pipelines" Version="10.0.0" GeneratePathProperty="true" PrivateAssets="all" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\Mgx.Engine\Mgx.Engine.csproj" />
</ItemGroup>

<Target Name="CopyPipelinesDependency" AfterTargets="Build">
<Copy SourceFiles="$(PkgSystem_IO_Pipelines)\lib\net10.0\System.IO.Pipelines.dll" DestinationFolder="$(TargetDir)" SkipUnchangedFiles="true" />
</Target>

<!-- Stage DLLs into the module folder so IDE builds are never stale. Release only, a Debug
dotnet test would otherwise overwrite a Release-staged module -->
<Target Name="StageModuleOutput" AfterTargets="Build" Condition="'$(Configuration)' == 'Release'">

<Target Name="StageModuleOutput" AfterTargets="Build" DependsOnTargets="CopyPipelinesDependency" Condition="'$(Configuration)' == 'Release'">
<PropertyGroup>
<ModuleRoot>$(MSBuildThisFileDirectory)..\..\Modules\M365DSC.mgx</ModuleRoot>
<DepsDir>$(ModuleRoot)\Dependencies</DepsDir>
Expand All @@ -44,6 +51,7 @@
<!-- ALC-isolated dependencies -->
<Copy SourceFiles="$(TargetDir)Polly.Core.dll" DestinationFolder="$(DepsDir)" SkipUnchangedFiles="true" Condition="Exists('$(TargetDir)Polly.Core.dll')" />
<Copy SourceFiles="$(TargetDir)System.Threading.RateLimiting.dll" DestinationFolder="$(DepsDir)" SkipUnchangedFiles="true" Condition="Exists('$(TargetDir)System.Threading.RateLimiting.dll')" />
<Copy SourceFiles="$(TargetDir)System.IO.Pipelines.dll" DestinationFolder="$(DepsDir)" SkipUnchangedFiles="true" Condition="Exists('$(TargetDir)System.IO.Pipelines.dll')" />
</Target>

</Project>
4 changes: 2 additions & 2 deletions tests/Unit/Mgx.Manifest.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ Describe 'Module payload' {
}

It 'isolates third-party dependencies under Dependencies/' {
# Polly and RateLimiting load through the ALC Resolving handler
foreach ($file in @('Polly.Core.dll', 'System.Threading.RateLimiting.dll'))
# Polly, RateLimiting and Pipelines load through the ALC Resolving handler
foreach ($file in @('Polly.Core.dll', 'System.Threading.RateLimiting.dll', 'System.IO.Pipelines.dll'))
{
Join-Path $script:Paths.ModuleRoot 'Dependencies' $file | Should -Exist
}
Expand Down