diff --git a/.editorconfig b/.editorconfig index 3a833bdb..979d170a 100644 --- a/.editorconfig +++ b/.editorconfig @@ -155,3 +155,11 @@ csharp_new_line_before_members_in_anonymous_types = true # Blocks are allowed csharp_prefer_braces = true:silent + +[*.cs] + +# SA1130: Use lambda syntax +dotnet_diagnostic.SA1130.severity = silent + +[*.sln] +indent_style = tab diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 0893b308..2102ba9b 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -14,6 +14,9 @@ with any additional questions or comments. ## Prerequisites +All dependencies can be installed by running the `init.ps1` script at the root of the repository +using Windows PowerShell or [PowerShell Core][pwsh] (on any OS). + The only prerequisite for building, testing, and deploying from this repository is the [.NET SDK](https://get.dot.net/). You should install the version specified in `global.json` or a later version within @@ -22,11 +25,6 @@ For example if 2.2.300 is specified, you may install 2.2.300, 2.2.301, or 2.2.31 while the 2.2.400 version would not be considered compatible by .NET SDK. See [.NET Core Versioning](https://docs.microsoft.com/en-us/dotnet/core/versions/) for more information. -All dependencies can be installed by running the `init.ps1` script at the root of the repository -using Windows PowerShell or [PowerShell Core][pwsh] (on any OS). - -This repository can be built on Windows, Linux, and OSX. - ## Package restore The easiest way to restore packages may be to run `init.ps1` which automatically authenticates @@ -35,6 +33,8 @@ to the feeds that packages for this repo come from, if any. ## Building +This repository can be built on Windows, Linux, and OSX. + Building, testing, and packing this repository can be done by using the standard dotnet CLI commands (e.g. `dotnet build`, `dotnet test`, `dotnet pack`, etc.). [pwsh]: https://docs.microsoft.com/en-us/powershell/scripting/install/installing-powershell?view=powershell-6 diff --git a/Directory.Build.props b/Directory.Build.props new file mode 100644 index 00000000..90fce7ac --- /dev/null +++ b/Directory.Build.props @@ -0,0 +1,44 @@ + + + Debug + $(MSBuildThisFileDirectory) + $(RepoRootPath)obj\$(MSBuildProjectName)\ + $(RepoRootPath)bin\$(MSBuildProjectName)\ + $(RepoRootPath)bin\Packages\$(Configuration)\NuGet\ + 8.0 + enable + true + + COMPANY-PLACEHOLDER + COMPANY-PLACEHOLDER + © COMPANY-PLACEHOLDER. All rights reserved. + MIT + true + true + true + snupkg + + 2.0.58 + + + + + + + + + + + + + + + + + + + + + + diff --git a/Directory.Build.targets b/Directory.Build.targets new file mode 100644 index 00000000..8c119d54 --- /dev/null +++ b/Directory.Build.targets @@ -0,0 +1,2 @@ + + diff --git a/Expand-Template.ps1 b/Expand-Template.ps1 old mode 100644 new mode 100755 index c98186e7..c0fdfb56 --- a/Expand-Template.ps1 +++ b/Expand-Template.ps1 @@ -1,3 +1,5 @@ +#!/usr/bin/env pwsh + <# .SYNOPSIS Expands this template into an actual project, taking values for placeholders @@ -79,37 +81,37 @@ try { git mv Library.sln "$LibraryName.sln" git mv src/Library/Library.csproj "src/Library/$LibraryName.csproj" git mv src/Library "src/$LibraryName" - git mv src/Library.Tests/Library.Tests.csproj "src/Library.Tests/$LibraryName.Tests.csproj" - git mv src/Library.Tests "src/$LibraryName.Tests" + git mv test/Library.Tests/Library.Tests.csproj "test/Library.Tests/$LibraryName.Tests.csproj" + git mv test/Library.Tests "test/$LibraryName.Tests" # Refresh solution file both to update paths and give the projects unique GUIDs dotnet sln remove src/Library/Library.csproj - dotnet sln remove src/Library.Tests/Library.Tests.csproj + dotnet sln remove test/Library.Tests/Library.Tests.csproj dotnet sln add "src/$LibraryName" - dotnet sln add "src/$LibraryName.Tests" + dotnet sln add "test/$LibraryName.Tests" git add "$LibraryName.sln" # Update project reference in test project. Add before removal to keep the same ItemGroup in place. - dotnet add "src/$LibraryName.Tests" reference "src/$LibraryName" - dotnet remove "src/$LibraryName.Tests" reference src/Library/Library.csproj - git add "src/$LibraryName.Tests/$LibraryName.Tests.csproj" + dotnet add "test/$LibraryName.Tests" reference "src/$LibraryName" + dotnet remove "test/$LibraryName.Tests" reference src/Library/Library.csproj + git add "test/$LibraryName.Tests/$LibraryName.Tests.csproj" # Replace placeholders in source files Replace-Placeholders -Path "src/$LibraryName/Calculator.cs" -Replacements @{ 'Library'=$LibraryName 'COMPANY-PLACEHOLDER'=$Author } - Replace-Placeholders -Path "src/$LibraryName.Tests/CalculatorTests.cs" -Replacements @{ + Replace-Placeholders -Path "test/$LibraryName.Tests/CalculatorTests.cs" -Replacements @{ 'Library'=$LibraryName 'COMPANY-PLACEHOLDER'=$Author } Replace-Placeholders -Path "LICENSE" -Replacements @{ 'COMPANY-PLACEHOLDER'=$Author } - Replace-Placeholders -Path "src/stylecop.json" -Replacements @{ + Replace-Placeholders -Path "stylecop.json" -Replacements @{ 'COMPANY-PLACEHOLDER'=$Author } - Replace-Placeholders -Path "src/Directory.Build.props" -Replacements @{ + Replace-Placeholders -Path "Directory.Build.props" -Replacements @{ 'COMPANY-PLACEHOLDER'=$Author } Replace-Placeholders -Path "README.md" -Replacements @{ @@ -145,7 +147,6 @@ try { } # Self destruct - $Invocation = (Get-Variable MyInvocation -Scope 1).Value git rm Expand-Template.* git rm :/azure-pipelines/expand-template.yml @@ -173,4 +174,4 @@ try { } # When testing this script, all the changes can be quickly reverted with this command: -# git reset HEAD :/README.md :/LICENSE :/azure-pipelines.yml :/src :/azure-pipelines; git co -- :/README.md :/LICENSE :/azure-pipelines.yml :/src :/azure-pipelines; git clean -fd :/src +# git reset HEAD :/README.md :/LICENSE :/azure-pipelines.yml :/src :/test :/azure-pipelines; git co -- :/README.md :/LICENSE :/azure-pipelines.yml :/src :/azure-pipelines; git clean -fd :/src :/test diff --git a/Library.sln b/Library.sln index d034f5b2..606811aa 100644 --- a/Library.sln +++ b/Library.sln @@ -5,21 +5,34 @@ VisualStudioVersion = 16.0.29322.22 MinimumVisualStudioVersion = 15.0.26124.0 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Library", "src\Library\Library.csproj", "{C06D702E-6FC7-453B-BDDF-608F825EC003}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Library.Tests", "src\Library.Tests\Library.Tests.csproj", "{DC5F3D1C-A9A3-44B7-A3C0-82C1FF4C3336}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Library.Tests", "test\Library.Tests\Library.Tests.csproj", "{DC5F3D1C-A9A3-44B7-A3C0-82C1FF4C3336}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{1CE9670B-D5FF-46A7-9D00-24E70E6ED48B}" ProjectSection(SolutionItems) = preProject .editorconfig = .editorconfig - src\Directory.Build.props = src\Directory.Build.props - src\Directory.Build.targets = src\Directory.Build.targets + Directory.Build.props = Directory.Build.props + Directory.Build.targets = Directory.Build.targets global.json = global.json nuget.config = nuget.config - src\shipping.ruleset = src\shipping.ruleset - src\stylecop.json = src\stylecop.json - src\tests.ruleset = src\tests.ruleset + README.md = README.md + stylecop.json = stylecop.json version.json = version.json EndProjectSection EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{9E154A29-1796-4B85-BD81-B6A385D8FF71}" + ProjectSection(SolutionItems) = preProject + src\.editorconfig = src\.editorconfig + src\Directory.Build.props = src\Directory.Build.props + src\Directory.Build.targets = src\Directory.Build.targets + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{36CCE840-6FE5-4DB9-A8D5-8CF3CB6D342A}" + ProjectSection(SolutionItems) = preProject + test\.editorconfig = test\.editorconfig + test\Directory.Build.props = test\Directory.Build.props + test\Directory.Build.targets = test\Directory.Build.targets + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -38,6 +51,10 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {9E154A29-1796-4B85-BD81-B6A385D8FF71} = {1CE9670B-D5FF-46A7-9D00-24E70E6ED48B} + {36CCE840-6FE5-4DB9-A8D5-8CF3CB6D342A} = {1CE9670B-D5FF-46A7-9D00-24E70E6ED48B} + EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {E3944F6A-384B-4B0F-B93F-3BD513DC57BD} EndGlobalSection diff --git a/README.md b/README.md index 1292f1f3..dbbb29cb 100644 --- a/README.md +++ b/README.md @@ -14,14 +14,14 @@ * Init script that installs prerequisites and auth helpers, supporting both non-elevation and elevation modes. * Static analyzers: [FxCop](https://docs.microsoft.com/en-us/visualstudio/code-quality/fxcop-analyzers?view=vs-2019) and [StyleCop](https://github.com/DotNetAnalyzers/StyleCopAnalyzers) * Read-only source tree (builds to top-level bin/obj folders) -* Auto-versioning (via [Nerdbank.GitVersioning](https://github.com/aarnott/nerdbank.gitversioning)) +* Auto-versioning (via [Nerdbank.GitVersioning](https://github.com/dotnet/nerdbank.gitversioning)) * Builds with a "pinned" .NET Core SDK to ensure reproducible builds across machines and across time. * Automatically pack the library and publish it as an artifact, and even push it to some NuGet feed for consumption. * Testing * Testing on .NET Framework, multiple .NET Core versions * Testing on Windows, Linux and OSX * Tests that crash or hang in Azure Pipelines automatically collect dumps and publish as a pipeline artifact for later investigation. -* Cloud build support: +* Cloud build support * YAML based build for long-term serviceability, and PR review opportunities for any changes. * Azure Pipelines and GitHub Action support * Emphasis on PowerShell scripts over reliance on tasks for a more locally reproducible build. diff --git a/azure-pipelines/artifacts/_stage_all.ps1 b/azure-pipelines/artifacts/_stage_all.ps1 index a05db529..4e6a6dbe 100644 --- a/azure-pipelines/artifacts/_stage_all.ps1 +++ b/azure-pipelines/artifacts/_stage_all.ps1 @@ -33,7 +33,7 @@ function Create-SymbolicLink { if ($IsMacOS -or $IsLinux) { ln $Target $Link | Out-Null } else { - cmd /c mklink $Link $Target | Out-Null + cmd /c "mklink `"$Link`" `"$Target`"" | Out-Null } } diff --git a/azure-pipelines/artifacts/testResults.ps1 b/azure-pipelines/artifacts/testResults.ps1 index bc9e0467..1e4c4c4e 100644 --- a/azure-pipelines/artifacts/testResults.ps1 +++ b/azure-pipelines/artifacts/testResults.ps1 @@ -5,8 +5,8 @@ if ($env:AGENT_TEMPDIRECTORY) { $env:AGENT_TEMPDIRECTORY = (Get-ChildItem $env:AGENT_TEMPDIRECTORY -Directory |? { $_.Name -match $guidRegex } |% { Get-ChildItem "$($_.FullName)\testhost*.dmp","$($_.FullName)\Sequence_*.xml" -Recurse }); } } else { - $srcRoot = Resolve-Path "$PSScriptRoot\..\..\src" + $testRoot = Resolve-Path "$PSScriptRoot\..\..\test" @{ - $srcRoot = (Get-ChildItem "$srcRoot\TestResults" -Recurse -Directory | Get-ChildItem -Recurse -File); + $testRoot = (Get-ChildItem "$testRoot\TestResults" -Recurse -Directory | Get-ChildItem -Recurse -File); } } diff --git a/azure-pipelines/install-dependencies.yml b/azure-pipelines/install-dependencies.yml index 51cf839d..5b1ac4af 100644 --- a/azure-pipelines/install-dependencies.yml +++ b/azure-pipelines/install-dependencies.yml @@ -4,7 +4,8 @@ parameters: steps: - powershell: | - .\init.ps1 ${{ parameters['initArgs'] }} -UpgradePrerequisites + $AccessToken = '$(System.AccessToken)' # Avoid specifying the access token directly on the init.ps1 command line to avoid it showing up in errors + .\init.ps1 -AccessToken $AccessToken ${{ parameters['initArgs'] }} -UpgradePrerequisites dotnet --info displayName: Install prerequisites diff --git a/global.json b/global.json index 0275fa5c..11833de0 100644 --- a/global.json +++ b/global.json @@ -1,6 +1,6 @@ { "sdk": { - "version": "3.1.201", + "version": "3.1.301", "rollForward": "patch", "allowPrerelease": false } diff --git a/init.ps1 b/init.ps1 index 0fa4bc43..b46aec28 100755 --- a/init.ps1 +++ b/init.ps1 @@ -63,6 +63,9 @@ $EnvVars = @{} if (!$NoPrerequisites) { & "$PSScriptRoot\tools\Install-NuGetCredProvider.ps1" -AccessToken $AccessToken -Force:$UpgradePrerequisites & "$PSScriptRoot\tools\Install-DotNetSdk.ps1" -InstallLocality $InstallLocality + if ($LASTEXITCODE -eq 3010) { + Exit 3010 + } # The procdump tool and env var is required for dotnet test to collect hang/crash dumps of tests. # But it only works on Windows. diff --git a/src/.editorconfig b/src/.editorconfig new file mode 100644 index 00000000..e69de29b diff --git a/src/Directory.Build.props b/src/Directory.Build.props index 5982b2f3..165d2ddd 100644 --- a/src/Directory.Build.props +++ b/src/Directory.Build.props @@ -1,44 +1,7 @@ - + + + - Debug - $([System.IO.Path]::GetFullPath('$(MSBuildThisFileDirectory)..\')) - $(RepoRootPath)obj\$(MSBuildProjectName)\ - $(RepoRootPath)bin\$(MSBuildProjectName)\ - $(RepoRootPath)bin\Packages\$(Configuration)\NuGet\ - 8.0 - enable - true - - COMPANY-PLACEHOLDER - COMPANY-PLACEHOLDER - © COMPANY-PLACEHOLDER. All rights reserved. - MIT - true - true - true - snupkg - - 2.0.58 - - - - - - - - - - - - - - - - - - - - - + netstandard2.0 + diff --git a/src/Directory.Build.targets b/src/Directory.Build.targets index 8f529fae..c1ce3634 100644 --- a/src/Directory.Build.targets +++ b/src/Directory.Build.targets @@ -3,10 +3,6 @@ false - - cobertura - [xunit.*]* - - $(OutputPath)/ - + + diff --git a/src/Library.Tests/Library.Tests.csproj b/src/Library.Tests/Library.Tests.csproj deleted file mode 100644 index 80e19b72..00000000 --- a/src/Library.Tests/Library.Tests.csproj +++ /dev/null @@ -1,24 +0,0 @@ - - - - net472;netcoreapp2.1;netcoreapp3.1 - false - $(NoWarn);CS1591 - true - ..\tests.ruleset - - - - - - - - - - - - - - - - diff --git a/src/Library/Library.csproj b/src/Library/Library.csproj index ae6eca97..61718a1f 100644 --- a/src/Library/Library.csproj +++ b/src/Library/Library.csproj @@ -1,8 +1,3 @@ - - netstandard2.0 - ..\shipping.ruleset - - diff --git a/src/shipping.ruleset b/src/shipping.ruleset deleted file mode 100644 index 72903546..00000000 --- a/src/shipping.ruleset +++ /dev/null @@ -1,74 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/tests.ruleset b/src/tests.ruleset deleted file mode 100644 index a1365976..00000000 --- a/src/tests.ruleset +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - - - - - - - - - - - diff --git a/src/stylecop.json b/stylecop.json similarity index 100% rename from src/stylecop.json rename to stylecop.json diff --git a/test/.editorconfig b/test/.editorconfig new file mode 100644 index 00000000..89195dda --- /dev/null +++ b/test/.editorconfig @@ -0,0 +1,40 @@ +[*.cs] + +# SA1600: Elements should be documented +dotnet_diagnostic.SA1600.severity = silent + +# SA1601: Partial elements should be documented +dotnet_diagnostic.SA1601.severity = silent + +# SA1602: Enumeration items should be documented +dotnet_diagnostic.SA1602.severity = silent + +# SA1615: Element return value should be documented +dotnet_diagnostic.SA1615.severity = silent + +# VSTHRD103: Call async methods when in an async method +dotnet_diagnostic.VSTHRD103.severity = silent + +# VSTHRD111: Use .ConfigureAwait(bool) +dotnet_diagnostic.VSTHRD111.severity = none + +# VSTHRD200: Use Async suffix for async methods +dotnet_diagnostic.VSTHRD200.severity = silent + +# CA1303: Do not pass literals as localized parameters +dotnet_diagnostic.CA1303.severity = none + +# CS1591: Missing XML comment for publicly visible type or member +dotnet_diagnostic.CS1591.severity = silent + +# CA1707: Identifiers should not contain underscores +dotnet_diagnostic.CA1707.severity = silent + +# CA1062: Validate arguments of public methods +dotnet_diagnostic.CA1062.severity = suggestion + +# CA1063: Implement IDisposable Correctly +dotnet_diagnostic.CA1063.severity = silent + +# CA1816: Dispose methods should call SuppressFinalize +dotnet_diagnostic.CA1816.severity = silent diff --git a/test/Directory.Build.props b/test/Directory.Build.props new file mode 100644 index 00000000..7d026671 --- /dev/null +++ b/test/Directory.Build.props @@ -0,0 +1,14 @@ + + + + + net472;netcoreapp2.1;netcoreapp3.1 + false + true + + + + + + + diff --git a/test/Directory.Build.targets b/test/Directory.Build.targets new file mode 100644 index 00000000..2faab375 --- /dev/null +++ b/test/Directory.Build.targets @@ -0,0 +1,10 @@ + + + cobertura + [xunit.*]* + + $(OutputPath)/ + + + + diff --git a/src/Library.Tests/CalculatorTests.cs b/test/Library.Tests/CalculatorTests.cs similarity index 100% rename from src/Library.Tests/CalculatorTests.cs rename to test/Library.Tests/CalculatorTests.cs diff --git a/test/Library.Tests/Library.Tests.csproj b/test/Library.Tests/Library.Tests.csproj new file mode 100644 index 00000000..29ac7bf8 --- /dev/null +++ b/test/Library.Tests/Library.Tests.csproj @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + diff --git a/src/Library.Tests/app.config b/test/Library.Tests/app.config similarity index 100% rename from src/Library.Tests/app.config rename to test/Library.Tests/app.config diff --git a/tools/Install-DotNetSdk.ps1 b/tools/Install-DotNetSdk.ps1 index 8d77a9fe..be5f6a27 100755 --- a/tools/Install-DotNetSdk.ps1 +++ b/tools/Install-DotNetSdk.ps1 @@ -31,7 +31,7 @@ $sdkVersion = & "$PSScriptRoot/../azure-pipelines/variables/DotNetSdkVersion.ps1 # Search for all .NET Core runtime versions referenced from MSBuild projects and arrange to install them. $runtimeVersions = @() -Get-ChildItem "$PSScriptRoot\..\src\*.*proj" -Recurse |% { +Get-ChildItem "$PSScriptRoot\..\src\*.*proj","$PSScriptRoot\..\test\*.*proj","$PSScriptRoot\..\Directory.Build.props" -Recurse |% { $projXml = [xml](Get-Content -Path $_) $targetFrameworks = $projXml.Project.PropertyGroup.TargetFramework if (!$targetFrameworks) { @@ -77,8 +77,10 @@ Function Install-DotNet($Version, [switch]$Runtime) { Write-Host "Downloading .NET Core $sdkSubstring$Version..." $Installer = Get-InstallerExe -Version $Version -Runtime:$Runtime Write-Host "Installing .NET Core $sdkSubstring$Version..." - cmd /c start /wait $Installer /install /quiet - if ($LASTEXITCODE -ne 0) { + cmd /c start /wait $Installer /install /passive /norestart + if ($LASTEXITCODE -eq 3010) { + Write-Verbose "Restart required" + } elseif ($LASTEXITCODE -ne 0) { throw "Failure to install .NET Core SDK" } } @@ -92,20 +94,28 @@ $envVars = @{ } if ($InstallLocality -eq 'machine') { - if ($IsWindows) { + if ($IsMacOS -or $IsLinux) { + $DotNetInstallDir = '/usr/share/dotnet' + } else { + $restartRequired = $false if ($PSCmdlet.ShouldProcess(".NET Core SDK $sdkVersion", "Install")) { Install-DotNet -Version $sdkVersion + $restartRequired = $restartRequired -or ($LASTEXITCODE -eq 3010) } $runtimeVersions | Get-Unique |% { if ($PSCmdlet.ShouldProcess(".NET Core runtime $_", "Install")) { Install-DotNet -Version $_ -Runtime + $restartRequired = $restartRequired -or ($LASTEXITCODE -eq 3010) } } + if ($restartRequired) { + Write-Host -ForegroundColor Yellow "System restart required" + Exit 3010 + } + return - } else { - $DotNetInstallDir = '/usr/share/dotnet' } } elseif ($InstallLocality -eq 'repo') { $DotNetInstallDir = "$DotNetInstallScriptRoot/.dotnet" diff --git a/tools/Install-NuGetCredProvider.ps1 b/tools/Install-NuGetCredProvider.ps1 index 496dcd96..2b3fb6fb 100755 --- a/tools/Install-NuGetCredProvider.ps1 +++ b/tools/Install-NuGetCredProvider.ps1 @@ -46,14 +46,20 @@ if ($IsMacOS -or $IsLinux) { if ($AccessToken) { $endpoints = @() - $nugetConfig = [xml](Get-Content -Path "$PSScriptRoot\..\nuget.config") + $endpointURIs = @() + Get-ChildItem "$PSScriptRoot\..\nuget.config" -Recurse |% { + $nugetConfig = [xml](Get-Content -Path $_) - $nugetConfig.configuration.packageSources.add |? { ($_.value -match '^https://pkgs\.dev\.azure\.com/') -or ($_.value -match '^https://[\w\-]+\.pkgs\.visualstudio\.com/') } |% { - $endpoint = New-Object -TypeName PSObject - Add-Member -InputObject $endpoint -MemberType NoteProperty -Name endpoint -Value $_.value - Add-Member -InputObject $endpoint -MemberType NoteProperty -Name username -Value ado - Add-Member -InputObject $endpoint -MemberType NoteProperty -Name password -Value $AccessToken - $endpoints += $endpoint + $nugetConfig.configuration.packageSources.add |? { ($_.value -match '^https://pkgs\.dev\.azure\.com/') -or ($_.value -match '^https://[\w\-]+\.pkgs\.visualstudio\.com/') } |% { + if ($endpointURIs -notcontains $_.Value) { + $endpointURIs += $_.Value + $endpoint = New-Object -TypeName PSObject + Add-Member -InputObject $endpoint -MemberType NoteProperty -Name endpoint -Value $_.value + Add-Member -InputObject $endpoint -MemberType NoteProperty -Name username -Value ado + Add-Member -InputObject $endpoint -MemberType NoteProperty -Name password -Value $AccessToken + $endpoints += $endpoint + } + } } $auth = New-Object -TypeName PSObject