diff --git a/.azure-pipelines/build_jobs.yml b/.azure-pipelines/build_jobs.yml
index 0ea43f5ce..d4d5b08e9 100644
--- a/.azure-pipelines/build_jobs.yml
+++ b/.azure-pipelines/build_jobs.yml
@@ -113,3 +113,24 @@ jobs:
inputs:
path: $(System.DefaultWorkingDirectory)/openxr_loader
artifact: openxr_loader_windows
+
+ - task: PowerShell@2
+ displayName: Stage loader and headers for NuGet
+ inputs:
+ filePath: $(System.DefaultWorkingDirectory)/.azure-pipelines/nuget/stage_nuget.ps1
+ arguments:
+ $(System.DefaultWorkingDirectory)/openxr_loader `
+ $(Build.SourcesDirectory)/specification/Makefile `
+ $(System.DefaultWorkingDirectory)/openxr_loader_staging
+ - task: NuGetCommand@2
+ displayName: Package for NuGet
+ inputs:
+ command: pack
+ packagesToPack: $(System.DefaultWorkingDirectory)/openxr_loader_staging/OpenXR.Loader.nuspec
+ packDestination: $(System.DefaultWorkingDirectory)/nuget
+ - task: PublishPipelineArtifact@1
+ displayName: Publish NuGet Package
+ condition: succeeded()
+ inputs:
+ path: $(System.DefaultWorkingDirectory)/nuget
+ artifact: NuGet
\ No newline at end of file
diff --git a/.azure-pipelines/nuget/NugetTemplate/OpenXR.Loader.nuspec b/.azure-pipelines/nuget/NugetTemplate/OpenXR.Loader.nuspec
new file mode 100644
index 000000000..eda5fc990
--- /dev/null
+++ b/.azure-pipelines/nuget/NugetTemplate/OpenXR.Loader.nuspec
@@ -0,0 +1,15 @@
+
+
+
+ OpenXR.Loader
+
+ Khronos Group
+ Khronos Group
+ false
+ Apache-2.0
+ https://licenses.nuget.org/Apache-2.0
+ https://github.com/KhronosGroup/OpenXR-SDK
+ Khronos OpenXR loader and headers required to build a Win32 or UWP OpenXR application
+ native khronos openxr loader
+
+
\ No newline at end of file
diff --git a/.azure-pipelines/nuget/NugetTemplate/build/native/OpenXR.Loader.props b/.azure-pipelines/nuget/NugetTemplate/build/native/OpenXR.Loader.props
new file mode 100644
index 000000000..4efdb7c86
--- /dev/null
+++ b/.azure-pipelines/nuget/NugetTemplate/build/native/OpenXR.Loader.props
@@ -0,0 +1,5 @@
+
+
+ $(MSBuildThisFileDirectory)..\..\
+
+
diff --git a/.azure-pipelines/nuget/NugetTemplate/build/native/OpenXR.Loader.targets b/.azure-pipelines/nuget/NugetTemplate/build/native/OpenXR.Loader.targets
new file mode 100644
index 000000000..fb4ec7601
--- /dev/null
+++ b/.azure-pipelines/nuget/NugetTemplate/build/native/OpenXR.Loader.targets
@@ -0,0 +1,38 @@
+
+
+
+
+
+ $(OpenXRPackageRoot)native\$(Platform)_uwp\release
+
+
+
+
+ $(OpenXRPackageRoot)native\$(Platform)\release
+
+
+
+
+
+
+ %(AdditionalIncludeDirectories);$(OpenXRPackageRoot)include
+
+
+ %(AdditionalDependencies);$(OpenXRLoaderBinaryRoot)\lib\openxr_loader.lib
+
+
+
+
+
+
+ %(Filename)%(Extension)
+ PreserveNewest
+ true
+
+
+
+
+
+
+
+
diff --git a/.azure-pipelines/nuget/stage_nuget.ps1 b/.azure-pipelines/nuget/stage_nuget.ps1
new file mode 100644
index 000000000..e2d83cdf8
--- /dev/null
+++ b/.azure-pipelines/nuget/stage_nuget.ps1
@@ -0,0 +1,74 @@
+param(
+ [Parameter(Mandatory=$true, HelpMessage="Path to unzipped openxr_loader_windows OpenXR-SDK release asset")]
+ $SDKRelease,
+ [Parameter(Mandatory=$true, HelpMessage="Path to specification Makefile. Needed to extract the version")]
+ $SpecMakefile,
+ [Parameter(Mandatory=$true, HelpMessage="Path create staged nuget directory layout")]
+ $NugetStaging)
+
+$ErrorActionPreference = "Stop"
+
+if (-Not (Test-Path $SDKRelease)) {
+ Throw "SDK Release folder not found: $SDKRelease"
+}
+if (-Not (Test-Path $SpecMakefile)) {
+ Throw "Specification makefile not found: $SpecMakefile"
+}
+
+$NugetTemplate = Join-Path $PSScriptRoot "NugetTemplate"
+
+if (Test-Path $NugetStaging) {
+ Remove-Item $NugetStaging -Recurse
+}
+
+#
+# Extract version from Specification makefile
+#
+$VersionMatch = Select-String -Path $SpecMakefile -Pattern "^SPECREVISION\s*=\s*(.+)"
+$SDKVersion = $VersionMatch.Matches[0].Groups[1]
+
+#
+# Start off using the NuGet template.
+#
+echo "Copy-Item $NugetTemplate $NugetStaging -Recurse"
+Copy-Item $NugetTemplate $NugetStaging -Recurse
+
+#
+# Update the NuSpec
+#
+$NuSpecPath = Resolve-Path (Join-Path $NugetStaging "OpenXR.Loader.nuspec")
+$xml = [xml](Get-Content $NuSpecPath)
+$nsm = New-Object Xml.XmlNamespaceManager($xml.NameTable)
+$nsm.AddNamespace("ng", "http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd")
+$xml.SelectSingleNode("/ng:package/ng:metadata/ng:version", $nsm).InnerText = $SDKVersion
+$xml.Save($NuSpecPath)
+
+#
+# Copy in the headers from the SDK release.
+#
+Copy-Item (Join-Path $SDKRelease "include") (Join-Path $NugetStaging "include") -Recurse
+
+#
+# Copy in the binaries from the SDK release.
+#
+function CopyLoader($Platform)
+{
+ $PlatformSDKPath = Join-Path $SDKRelease "$Platform"
+ $NuGetPlatformPath = Join-Path $NugetStaging "native/$Platform/release"
+
+ $NugetLibPath = Join-Path $NuGetPlatformPath "lib"
+ New-Item $NugetLibPath -ItemType "directory" -Force
+ Copy-Item (Join-Path $PlatformSDKPath "lib/openxr_loader.lib") $NugetLibPath
+
+ $NugetBinPath = Join-Path $NuGetPlatformPath "bin"
+ New-Item $NugetBinPath -ItemType "directory" -Force
+ Copy-Item (Join-Path $PlatformSDKPath "bin/openxr_loader.dll") $NugetBinPath
+}
+
+# Currently there are no non-UWP ARM/ARM64 binaries available from the SDK release.
+CopyLoader "x64"
+CopyLoader "Win32"
+CopyLoader "x64_uwp"
+CopyLoader "Win32_uwp"
+CopyLoader "arm64_uwp"
+CopyLoader "arm_uwp"
\ No newline at end of file
diff --git a/changes/sdk/pr.196.gh.OpenXR-SDK-Source.md b/changes/sdk/pr.196.gh.OpenXR-SDK-Source.md
new file mode 100644
index 000000000..ba8ee5bff
--- /dev/null
+++ b/changes/sdk/pr.196.gh.OpenXR-SDK-Source.md
@@ -0,0 +1 @@
+Modifications to Azure DevOps build pipeline to automatically generate a NuGet package.
\ No newline at end of file