mirror of
				https://github.com/winfsp/winfsp.git
				synced 2025-10-30 19:48:38 -05:00 
			
		
		
		
	tools: make-release.ps1: automate submissions to hardware dashboard
This commit is contained in:
		| @@ -68,6 +68,27 @@ function Get-ReleaseInfo ($Tag) { | |||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | function Get-HwapiCredentials { | ||||||
|  |     $Credentials = (& "$ProjectRoot\tools\wincred.ps1" get "Hardware Dashboard API") | ||||||
|  |     if ($Credentials) { | ||||||
|  |         try { $Credentials = ConvertFrom-Json $Credentials[1] } catch {;} | ||||||
|  |     } | ||||||
|  |     if ($Credentials -and $Credentials.TenantId -and $Credentials.ClientId -and $Credentials.ClientId) { | ||||||
|  |         return $Credentials | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function Start-Sdcm { | ||||||
|  |     Start-Job -ArgumentList $args -ScriptBlock { | ||||||
|  |         $env:SDCM_CREDS_TENANTID = $using:HwapiCredentials.TenantId | ||||||
|  |         $env:SDCM_CREDS_CLIENTID = $using:HwapiCredentials.ClientId | ||||||
|  |         $env:SDCM_CREDS_KEY = $using:HwapiCredentials.Key | ||||||
|  |         $env:SDCM_CREDS_URL = "https://manage.devcenter.microsoft.com" | ||||||
|  |         $env:SDCM_CREDS_URLPREFIX = "v2.0/my" | ||||||
|  |         & "$using:ProjectRoot\..\winfsp.sdcm\SurfaceDevCenterManager\bin\Debug\sdcm.exe" -creds envonly @args | ||||||
|  |     } | Receive-Job -Wait -AutoRemoveJob | ||||||
|  | } | ||||||
|  |  | ||||||
| function Get-FileVersion ($FileName) { | function Get-FileVersion ($FileName) { | ||||||
|     return [System.Diagnostics.FileVersionInfo]::GetVersionInfo($FileName).FileVersion |     return [System.Diagnostics.FileVersionInfo]::GetVersionInfo($FileName).FileVersion | ||||||
| } | } | ||||||
| @@ -96,6 +117,12 @@ function Check-Prerequisites { | |||||||
|         exit 1 |         exit 1 | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     # check scdm.exe | ||||||
|  |     if (!(Get-Command "$ProjectRoot\..\winfsp.sdcm\SurfaceDevCenterManager\bin\Debug\sdcm.exe" -ErrorAction SilentlyContinue)) { | ||||||
|  |         Write-Stderr "error: cannot find sdcm.exe" | ||||||
|  |         exit 1 | ||||||
|  |     } | ||||||
|  |  | ||||||
|     # check gh.exe |     # check gh.exe | ||||||
|     if (!(Get-Command "gh.exe" -ErrorAction SilentlyContinue)) { |     if (!(Get-Command "gh.exe" -ErrorAction SilentlyContinue)) { | ||||||
|         Write-Stderr "error: cannot find gh.exe" |         Write-Stderr "error: cannot find gh.exe" | ||||||
| @@ -137,6 +164,17 @@ function Check-Prerequisites { | |||||||
|         exit 1 |         exit 1 | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |     # check hardware dashboard api credentials | ||||||
|  |     $script:HwapiCredentials = Get-HwapiCredentials | ||||||
|  |     if (!$script:HwapiCredentials) { | ||||||
|  |         Write-Stderr "error: cannot get Hardware Dashboard API credentials" | ||||||
|  |         Write-Stderr '    The expected format of the credentials is as follows:' | ||||||
|  |         Write-Stderr '    TargetName: Hardware Dashboard API' | ||||||
|  |         Write-Stderr '    UserName: Credentials' | ||||||
|  |         Write-Stderr '    Password: {"TenantId":"TENANTID","ClientId":"CLIENTID","Key":"KEY"}' | ||||||
|  |         exit 1 | ||||||
|  |     } | ||||||
|  |  | ||||||
|     if ($State -contains $Name) { |     if ($State -contains $Name) { | ||||||
|         if (!($State -contains "$Tag-$CommitCount-g$Commit")) { |         if (!($State -contains "$Tag-$CommitCount-g$Commit")) { | ||||||
|             Write-Stderr "error: invalid state for tag $Tag" |             Write-Stderr "error: invalid state for tag $Tag" | ||||||
| @@ -149,6 +187,12 @@ function Check-Prerequisites { | |||||||
| } | } | ||||||
|  |  | ||||||
| function Check-Assets { | function Check-Assets { | ||||||
|  |     # check driver.cab | ||||||
|  |     if (!(Test-Path "$ProjectRoot\build\VStudio\build\Release\driver.cab" -ErrorAction SilentlyContinue)) { | ||||||
|  |         Write-Stderr "error: cannot find driver.cab" | ||||||
|  |         exit 1 | ||||||
|  |     } | ||||||
|  |  | ||||||
|     # check winfsp.msi |     # check winfsp.msi | ||||||
|     if (!(Test-Path "$ProjectRoot\build\VStudio\build\Release\winfsp*.msi" -ErrorAction SilentlyContinue)) { |     if (!(Test-Path "$ProjectRoot\build\VStudio\build\Release\winfsp*.msi" -ErrorAction SilentlyContinue)) { | ||||||
|         Write-Stderr "error: cannot find winfsp*.msi" |         Write-Stderr "error: cannot find winfsp*.msi" | ||||||
| @@ -192,8 +236,215 @@ function Build-AssetsPhase1 { | |||||||
|  |  | ||||||
|         Write-Stdout @" |         Write-Stdout @" | ||||||
|  |  | ||||||
| Upload file driver.cab to Microsoft Partner Center for attestation signing. | Assets have been built but are not properly signed. | ||||||
| When the file has been signed, download and extract to ~\Downloads\drivers | Signable assets are ready for submission to the hardware dashboard. | ||||||
|  |  | ||||||
|  | "@ | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function Submit-AssetsToHwapi { | ||||||
|  |     Task -ScriptBlock { | ||||||
|  |         Check-Assets | ||||||
|  |  | ||||||
|  |         $MsiFile = Resolve-Path "$ProjectRoot\build\VStudio\build\Release\winfsp*.msi" | ||||||
|  |         $MsiName = Split-Path -Leaf $MsiFile | ||||||
|  |         if ($MsiName -match "winfsp-(.+)\.msi") { | ||||||
|  |             $Version = $matches[1] | ||||||
|  |         } | ||||||
|  |         if (!$Version) { | ||||||
|  |             Write-Stderr "error: cannot determine version for winfsp.msi" | ||||||
|  |             exit 1 | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         $DocRequestedSignatures = @() | ||||||
|  |         $Documentation = Invoke-WebRequest -Uri "https://raw.githubusercontent.com/MicrosoftDocs/windows-driver-docs/staging/windows-driver-docs-pr/dashboard/get-product-data.md" | ||||||
|  |         $Documentation = $Documentation.Content | ||||||
|  |         $List = $false | ||||||
|  |         foreach ($Line in $Documentation -Split "`n") { | ||||||
|  |             if ($Line -match "^### List of Operating System Codes") { | ||||||
|  |                 $List = $true | ||||||
|  |             } elseif ($Line -match "^###") { | ||||||
|  |                 $List = $false | ||||||
|  |             } elseif ($List -and $Line -cmatch "\| *(WINDOWS_v100_[^| ]+) *\|") { | ||||||
|  |                 $DocRequestedSignatures += $matches[1] | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         if ($DocRequestedSignatures.length -lt 32) { | ||||||
|  |             Write-Stderr "error: cannot determine signatures to request" | ||||||
|  |             Write-Stderr '    Does the document at the URL below still contain a "List of Operating System Codes":' | ||||||
|  |             Write-Stderr "    https://raw.githubusercontent.com/MicrosoftDocs/windows-driver-docs/staging/windows-driver-docs-pr/dashboard/get-product-data.md" | ||||||
|  |             exit 1 | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         # start with the base signatures and add any new ones found in the docs | ||||||
|  |         $RequestedSignatures = @( | ||||||
|  |             "WINDOWS_v100_TH2_FULL" | ||||||
|  |             "WINDOWS_v100_X64_TH2_FULL" | ||||||
|  |             "WINDOWS_v100_RS1_FULL" | ||||||
|  |             "WINDOWS_v100_X64_RS1_FULL" | ||||||
|  |             "WINDOWS_v100_RS2_FULL" | ||||||
|  |             "WINDOWS_v100_X64_RS2_FULL" | ||||||
|  |             "WINDOWS_v100_RS3_FULL" | ||||||
|  |             "WINDOWS_v100_X64_RS3_FULL" | ||||||
|  |             "WINDOWS_v100_ARM64_RS3_FULL" | ||||||
|  |             "WINDOWS_v100_RS4_FULL" | ||||||
|  |             "WINDOWS_v100_X64_RS4_FULL" | ||||||
|  |             "WINDOWS_v100_ARM64_RS4_FULL" | ||||||
|  |             "WINDOWS_v100_RS5_FULL" | ||||||
|  |             "WINDOWS_v100_X64_RS5_FULL" | ||||||
|  |             "WINDOWS_v100_ARM64_RS5_FULL" | ||||||
|  |             "WINDOWS_v100_19H1_FULL" | ||||||
|  |             "WINDOWS_v100_X64_19H1_FULL" | ||||||
|  |             "WINDOWS_v100_ARM64_19H1_FULL" | ||||||
|  |             "WINDOWS_v100_VB_FULL" | ||||||
|  |             "WINDOWS_v100_X64_VB_FULL" | ||||||
|  |             "WINDOWS_v100_ARM64_VB_FULL" | ||||||
|  |             "WINDOWS_v100_X64_CO_FULL" | ||||||
|  |             "WINDOWS_v100_ARM64_CO_FULL" | ||||||
|  |             "WINDOWS_v100_X64_NI_FULL" | ||||||
|  |             "WINDOWS_v100_ARM64_NI_FULL" | ||||||
|  |         ) | ||||||
|  |         foreach ($Signature in $DocRequestedSignatures) { | ||||||
|  |             if ($RequestedSignatures -contains $Signature) { | ||||||
|  |                 continue | ||||||
|  |             } | ||||||
|  |             if ($Signature.Contains("_SERVER_")) { | ||||||
|  |                 continue | ||||||
|  |             } | ||||||
|  |             if ($Signature -eq "WINDOWS_v100_TH1_FULL") { | ||||||
|  |                 continue | ||||||
|  |             } | ||||||
|  |             if ($Signature -eq "WINDOWS_v100_X64_TH1_FULL") { | ||||||
|  |                 continue | ||||||
|  |             } | ||||||
|  |             $RequestedSignatures += $Signature | ||||||
|  |             Write-Stdout "New doc signature: $Signature" | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         $CreateProduct = @{ | ||||||
|  |             createType = "product" | ||||||
|  |             createProduct = @{ | ||||||
|  |                 productName = "winfsp-$Version" | ||||||
|  |                 testHarness = "attestation" | ||||||
|  |                 deviceType = "internalExternal" | ||||||
|  |                 requestedSignatures = $RequestedSignatures | ||||||
|  |                 # deviceMetaDataIds = $null | ||||||
|  |                 # firmwareVersion = "0" | ||||||
|  |                 # isTestSign = $false | ||||||
|  |                 # isFlightSign = $false | ||||||
|  |                 # markettingNames = $null | ||||||
|  |                 # selectedProductTypes = $null | ||||||
|  |                 # additionalAttributes = $null | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         $CreateSubmission = @{ | ||||||
|  |             createType = "submission" | ||||||
|  |             createSubmission = @{ | ||||||
|  |                 name = "winfsp-$Version" | ||||||
|  |                 type = "initial" | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         New-Item "$ProjectRoot\build\VStudio\build\Release\hwapi" -Type Directory -ErrorAction SilentlyContinue >$null | ||||||
|  |         ConvertTo-Json $CreateProduct | Out-File -Encoding Ascii "$ProjectRoot\build\VStudio\build\Release\hwapi\CreateProduct.json" | ||||||
|  |         ConvertTo-Json $CreateSubmission | Out-File -Encoding Ascii "$ProjectRoot\build\VStudio\build\Release\hwapi\CreateSubmission.json" | ||||||
|  |  | ||||||
|  |         Start-Sdcm -create "$ProjectRoot\build\VStudio\build\Release\hwapi\CreateProduct.json" | Tee-Object -Variable Output | ||||||
|  |         if ($LastExitCode -ne 0) { | ||||||
|  |             Write-Stderr "error: cannot create product on hardware dashboard" | ||||||
|  |             exit 1 | ||||||
|  |         } | ||||||
|  |         if (-not ([string]$Output -match "--- Product: (\d+)")) { | ||||||
|  |             Write-Stderr "error: cannot get product id from hardware dashboard" | ||||||
|  |             exit 1 | ||||||
|  |         } | ||||||
|  |         $ProductId = $matches[1] | ||||||
|  |  | ||||||
|  |         Start-Sdcm -create "$ProjectRoot\build\VStudio\build\Release\hwapi\CreateSubmission.json" -productid $ProductId  | Tee-Object -Variable Output | ||||||
|  |         if ($LastExitCode -ne 0) { | ||||||
|  |             Write-Stderr "error: cannot create submission on hardware dashboard" | ||||||
|  |             exit 1 | ||||||
|  |         } | ||||||
|  |         if (-not ([string]$Output -match "---- Submission: (\d+)")) { | ||||||
|  |             Write-Stderr "error: cannot get submission id from hardware dashboard" | ||||||
|  |             exit 1 | ||||||
|  |         } | ||||||
|  |         $SubmissionId = $matches[1] | ||||||
|  |  | ||||||
|  |         Set-Content "$ProjectRoot\build\VStudio\build\Release\hwapi\ProductId" -Value $ProductId | ||||||
|  |         Set-Content "$ProjectRoot\build\VStudio\build\Release\hwapi\SubmissionId" -Value $SubmissionId | ||||||
|  |  | ||||||
|  |         Write-Stdout @" | ||||||
|  |  | ||||||
|  | Product submission has been prepared on hardware dashboard. | ||||||
|  |  | ||||||
|  | "@ | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function Upload-AssetsToHwapi { | ||||||
|  |     Task -ScriptBlock { | ||||||
|  |         Check-Assets | ||||||
|  |  | ||||||
|  |         $ProductId = Get-Content "$ProjectRoot\build\VStudio\build\Release\hwapi\ProductId" | ||||||
|  |         $SubmissionId = Get-Content "$ProjectRoot\build\VStudio\build\Release\hwapi\SubmissionId" | ||||||
|  |  | ||||||
|  |         Start-Sdcm -upload "$ProjectRoot\build\VStudio\build\Release\driver.cab" -productid $ProductId -submissionid $SubmissionId | ||||||
|  |         if ($LastExitCode -ne 0) { | ||||||
|  |             Write-Stderr "error: cannot upload driver.cab to hardware dashboard" | ||||||
|  |             exit 1 | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         Start-Sdcm -commit -productid $ProductId -submissionid $SubmissionId | ||||||
|  |         if ($LastExitCode -ne 0) { | ||||||
|  |             Write-Stderr "error: cannot commit submission to hardware dashboard" | ||||||
|  |             exit 1 | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         Write-Stdout @" | ||||||
|  |  | ||||||
|  | Signable assets have been uploaded to the hardware dashboard. | ||||||
|  |  | ||||||
|  | "@ | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function Download-AssetsFromHwapi { | ||||||
|  |     Task -ScriptBlock { | ||||||
|  |         Check-Assets | ||||||
|  |  | ||||||
|  |         $ProductId = Get-Content "$ProjectRoot\build\VStudio\build\Release\hwapi\ProductId" | ||||||
|  |         $SubmissionId = Get-Content "$ProjectRoot\build\VStudio\build\Release\hwapi\SubmissionId" | ||||||
|  |  | ||||||
|  |         Remove-Item -Force "$ProjectRoot\build\VStudio\build\Release\hwapi\Signed-$SubmissionId.zip" -ErrorAction SilentlyContinue | ||||||
|  |         Remove-Item -Recurse -Force "$ProjectRoot\build\VStudio\build\Release\hwapi\drivers" -ErrorAction SilentlyContinue | ||||||
|  |  | ||||||
|  |         Start-Sdcm -download "$ProjectRoot\build\VStudio\build\Release\hwapi\Signed-$SubmissionId.zip" -productid $ProductId -submissionid $SubmissionId | ||||||
|  |         if ($LastExitCode -ne 0) { | ||||||
|  |             Write-Stderr "error: cannot download signed drivers from hardware dashboard" | ||||||
|  |             exit 1 | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (!(Test-Path "$ProjectRoot\build\VStudio\build\Release\hwapi\Signed-$SubmissionId.zip" -ErrorAction SilentlyContinue)) { | ||||||
|  |             Write-Stderr "error: cannot download signed drivers from hardware dashboard" | ||||||
|  |             exit 1 | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         $ExpandError = "" | ||||||
|  |         Expand-Archive "$ProjectRoot\build\VStudio\build\Release\hwapi\Signed-$SubmissionId.zip" -DestinationPath "$ProjectRoot\build\VStudio\build\Release\hwapi" -ErrorVariable ExpandError | ||||||
|  |         if ($ExpandError) { | ||||||
|  |             Write-Stderr "error: cannot expand signed drivers archive" | ||||||
|  |             exit 1 | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         if (!(Test-Path "$ProjectRoot\build\VStudio\build\Release\hwapi\drivers" -ErrorAction SilentlyContinue)) { | ||||||
|  |             Write-Stderr "error: cannot expand signed drivers archive" | ||||||
|  |             exit 1 | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         Write-Stdout @" | ||||||
|  |  | ||||||
|  | Signable assets have been downloaded and can be used to complete the build. | ||||||
|  |  | ||||||
| "@ | "@ | ||||||
|     } |     } | ||||||
| @@ -204,16 +455,16 @@ function Build-AssetsPhase2 { | |||||||
|         Check-Assets |         Check-Assets | ||||||
|  |  | ||||||
|         # check signed drivers folder |         # check signed drivers folder | ||||||
|         if (!(Test-Path ~\Downloads\drivers -ErrorAction SilentlyContinue)) { |         if (!(Test-Path "$ProjectRoot\build\VStudio\build\Release\hwapi\drivers" -ErrorAction SilentlyContinue)) { | ||||||
|             Write-Stderr "error: cannot find ~\Downloads\drivers" |             Write-Stderr "error: cannot find hwapi\drivers" | ||||||
|             exit 1 |             exit 1 | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         $SignedPackage = Resolve-Path ~\Downloads\drivers |         $SignedPackage = Resolve-Path "$ProjectRoot\build\VStudio\build\Release\hwapi\drivers" | ||||||
|  |  | ||||||
|         $VerX64 = Get-FileVersion "$ProjectRoot\build\VStudio\build\Release\winfsp-x64.sys" |         $VerX64 = Get-FileVersion "$ProjectRoot\build\VStudio\build\Release\winfsp-x64.sys" | ||||||
|         if ($VerX64 -ne (Get-FileVersion "$SignedPackage\x64\winfsp-x64.sys")) { |         if ($VerX64 -ne (Get-FileVersion "$SignedPackage\x64\winfsp-x64.sys")) { | ||||||
|             Write-Stderr "error: incompatible versions in ~\Downloads\drivers" |             Write-Stderr "error: incompatible versions in hwapi\drivers" | ||||||
|             exit 1 |             exit 1 | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -375,8 +626,12 @@ Check-Prerequisites | |||||||
|  |  | ||||||
| # Workflow tasks | # Workflow tasks | ||||||
| Build-AssetsPhase1 | Build-AssetsPhase1 | ||||||
|  | Submit-AssetsToHwapi | ||||||
|  | Upload-AssetsToHwapi | ||||||
|  | Download-AssetsFromHwapi | ||||||
| Build-AssetsPhase2 | Build-AssetsPhase2 | ||||||
| Make-GitHubRelease | Make-GitHubRelease | ||||||
| Upload-Symbols | Upload-Symbols | ||||||
| Make-NugetRelease | Make-NugetRelease | ||||||
| Make-ChocoRelease | Make-ChocoRelease | ||||||
|  | Write-Stdout "ALL COMPLETE" | ||||||
|   | |||||||
							
								
								
									
										124
									
								
								tools/wincred.ps1
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								tools/wincred.ps1
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,124 @@ | |||||||
|  | Start-Job -ArgumentList $args -ScriptBlock { | ||||||
|  | param ( | ||||||
|  |     [ValidateSet("get", "set", "del")] | ||||||
|  |     [string]$Command | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | Add-Type -TypeDefinition @" | ||||||
|  | using System; | ||||||
|  | using System.Runtime.InteropServices; | ||||||
|  | namespace Win32 | ||||||
|  | { | ||||||
|  |     public class Api | ||||||
|  |     { | ||||||
|  |         public static String[] CredRead( | ||||||
|  |             String TargetName) | ||||||
|  |         { | ||||||
|  |             String[] Result = null; | ||||||
|  |             IntPtr CredentialPtr; | ||||||
|  |             if (CredReadW(TargetName, 1/*CRED_TYPE_GENERIC*/, 0, out CredentialPtr)) | ||||||
|  |             { | ||||||
|  |                 CREDENTIALW Credential = Marshal.PtrToStructure<CREDENTIALW>(CredentialPtr); | ||||||
|  |                 Result = new String[2]{ | ||||||
|  |                     Credential.UserName, | ||||||
|  |                     Marshal.PtrToStringUni( | ||||||
|  |                         Credential.CredentialBlob, (int)Credential.CredentialBlobSize / 2) | ||||||
|  |                 }; | ||||||
|  |                 CredFree(CredentialPtr); | ||||||
|  |             } | ||||||
|  |             return Result; | ||||||
|  |         } | ||||||
|  |         public static Boolean CredWrite( | ||||||
|  |             String TargetName, | ||||||
|  |             String UserName, | ||||||
|  |             String Password) | ||||||
|  |         { | ||||||
|  |             CREDENTIALW Credential = new CREDENTIALW{ | ||||||
|  |                 Type = 1/*CRED_TYPE_GENERIC*/, | ||||||
|  |                 Persist = 2/*CRED_PERSIST_LOCAL_MACHINE*/, | ||||||
|  |                 TargetName = TargetName, | ||||||
|  |                 UserName = UserName, | ||||||
|  |                 CredentialBlobSize = (UInt32)Password.Length * 2, | ||||||
|  |                 CredentialBlob = Marshal.StringToCoTaskMemUni(Password), | ||||||
|  |             }; | ||||||
|  |             Boolean Result = CredWriteW(ref Credential, 0); | ||||||
|  |             Marshal.FreeCoTaskMem(Credential.CredentialBlob); | ||||||
|  |             return Result; | ||||||
|  |         } | ||||||
|  |         public static Boolean CredDelete( | ||||||
|  |             String TargetName) | ||||||
|  |         { | ||||||
|  |             return CredDeleteW(TargetName, 1/*CRED_TYPE_GENERIC*/, 0); | ||||||
|  |         } | ||||||
|  |         [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError=true)] | ||||||
|  |         [return: MarshalAs(UnmanagedType.U1)] | ||||||
|  |         private static extern Boolean CredReadW( | ||||||
|  |             String TargetName, | ||||||
|  |             UInt32 Type, | ||||||
|  |             UInt32 Flags, | ||||||
|  |             out IntPtr Credential); | ||||||
|  |         [DllImport("advapi32.dll")] | ||||||
|  |         private static extern void CredFree( | ||||||
|  |             IntPtr Buffer); | ||||||
|  |         [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError=true)] | ||||||
|  |         [return: MarshalAs(UnmanagedType.U1)] | ||||||
|  |         private static extern Boolean CredWriteW( | ||||||
|  |             ref CREDENTIALW Credential, | ||||||
|  |             UInt32 Flags); | ||||||
|  |         [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError=true)] | ||||||
|  |         [return: MarshalAs(UnmanagedType.U1)] | ||||||
|  |         private static extern Boolean CredDeleteW( | ||||||
|  |             String TargetName, | ||||||
|  |             UInt32 Type, | ||||||
|  |             UInt32 Flags); | ||||||
|  |         [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)] | ||||||
|  |         private struct CREDENTIALW | ||||||
|  |         { | ||||||
|  |             public UInt32 Flags; | ||||||
|  |             public UInt32 Type; | ||||||
|  |             public String TargetName; | ||||||
|  |             public String Comment; | ||||||
|  |             public UInt64 LastWritten; | ||||||
|  |             public UInt32 CredentialBlobSize; | ||||||
|  |             public IntPtr CredentialBlob; | ||||||
|  |             public UInt32 Persist; | ||||||
|  |             public UInt32 AttributeCount; | ||||||
|  |             public IntPtr Attributes; | ||||||
|  |             public String TargetAlias; | ||||||
|  |             public String UserName; | ||||||
|  |         }; | ||||||
|  |     }; | ||||||
|  | }; | ||||||
|  | "@ | ||||||
|  |  | ||||||
|  | function Get-WindowsCredential { | ||||||
|  |     param ( | ||||||
|  |         [Parameter(Mandatory)][string]$TargetName | ||||||
|  |     ) | ||||||
|  |     return [Win32.Api]::CredRead($TargetName) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function Set-WindowsCredential { | ||||||
|  |     param ( | ||||||
|  |         [Parameter(Mandatory)][string]$TargetName, | ||||||
|  |         [Parameter(Mandatory)][string]$UserName, | ||||||
|  |         [Parameter(Mandatory)][string]$Password | ||||||
|  |     ) | ||||||
|  |     return [Win32.Api]::CredWrite($TargetName, $UserName, $Password) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | function Delete-WindowsCredential { | ||||||
|  |     param ( | ||||||
|  |         [Parameter(Mandatory)][string]$TargetName | ||||||
|  |     ) | ||||||
|  |     return [Win32.Api]::CredDelete($TargetName) | ||||||
|  | } | ||||||
|  |  | ||||||
|  | $Function = @{ | ||||||
|  |     "get" = "Get-WindowsCredential" | ||||||
|  |     "set" = "Set-WindowsCredential" | ||||||
|  |     "del" = "Delete-WindowsCredential" | ||||||
|  | }[$Command] | ||||||
|  | & $Function @args | ||||||
|  |  | ||||||
|  | } | Receive-Job -Wait -AutoRemoveJob | ||||||
		Reference in New Issue
	
	Block a user