电源外壳 "Provider execution stopped because the provider does not support this operation."

Powershell "Provider execution stopped because the provider does not support this operation."

我正在尝试编写一个脚本来通过 FriendlyName 检查远程服务器的证书。退回后,我想确认删除此证书。 当前下面的代码 returns "Provider execution stopped because the provider does not support this operation." 为什么提供程序在 Remove-Item cmd 期间不工作,但在我使用 Select-Object 时在脚本中更早工作?

$Logfile = "C:\Cert_Deletions_$(get-date -Format MMddyyyy).log"

Function LogWrite
{
   Param ([string]$logstring)

   Add-content $Logfile -value $logstring
}

#$TimeStamp = Get-Date;

LogWrite "Starting Cert Deletion Job $(get-date)";



$ContentsPath = 'C:\Servers.txt'
$Servers = "Server01"
$CertDeletionFile = 'C:\CertsDeleted.csv'
$Today = Get-Date

$typedCertificateName = Read-Host -Prompt "What certificate would you like 
to REMOVE?"

LogWrite "What Certificate would you like to REMOVE?"

function findCert {
param ([string]$Certificate)

Invoke-Command -ComputerName $Servers -ScriptBlock {

    Get-Childitem -Path  Cert:LocalMachine\My |
        where-Object {$_.friendlyname -eq $using:Certificate } |
        Select-Object -Property FriendlyName
    }
}
#line break
"`n"
Write-host "The following servers were found to hold the 
$typedCertificateName certificate:"
LogWrite "The following servers were found to hold the $typedCertificateName 
certificate:"
#line break
"`n"
$LocatedOn = findCert -Certificate $typedCertificateName
$LocatedOn
LogWrite $LocatedOn

"`n"

Write-host "Do you want to delete all certificates for $typedCertificateName 
??" -ForegroundColor Red 
LogWrite "Do you want to delete all certificates for $typedCertificateName 
??"
$Readhost = Read-Host " ( y / n ) " 
Switch ($ReadHost) 
 { 
   Y {Write-host "Yes, Deleting Now!!!" -ForegroundColor Yellow; 
       $Choice=$true} 
   N {Write-Host "No, Do NOT DELETE" -ForegroundColor Red; $Choice=$false} 
   Default {Write-Host "Default, Do Not Delete"; $Choice=$false} 
 } 

 If ($Readhost -eq 'y' -or 'Y') {
    Foreach ($Server in $Servers) {
        Invoke-Command -ComputerName $Server -ScriptBlock {
            try {
                Get-Childitem -Path  Cert:LocalMachine\My |
                where-Object {$_.friendlyname -eq 
$using:typedCertificateName} |
                Remove-Item  -ErrorAction Stop
                Write-host "$using:typedCertificateName has been deleted on 
$Server."
                #LogWrite "$using:typedCertificateName has been deleted on 
$Server."
                }
                catch
                {
                write-host $error 
                }           
         }    
     }
  }

以下是如何在 PowerShell v2 上删除证书的示例,其中 Remove-Item cmdlet 不适用于证书删除。该脚本将首先进行删除,然后验证删除是否发生。随意修改您的目的:

<#
.SYNOPSIS
    Removes all 802.1x certificates in the 'Cert:\LocalMachine\My' certificate store on a Windows machine which fit the defined criteria.
.DESCRIPTION
    Removes all 802.1x certificates in the 'Cert:\LocalMachine\My' certificate store with the following criteria:

    Certificate Issuer: Company Internal Sub CA
    Certificate Created with Template Name: Company-802.1x-mach-auth-AE-v1.0
    Certificate Store: LocalMachine\My
.EXAMPLE
    powershell.exe -File '.\Remove-DcmAll8021xUniCERT.ps1'
    Returns 'Not Compliant' if ANY certificates REMAIN in 'Cert:\LocalMachine\My' that fit the criteria described above AFTER the removal step is performed.
    Returns 'Compliant' if no such certs are found AFTER the removal step is performed.
.NOTES
#>

## Start by setting the execution policy for this PowerShell process
Try { Set-ExecutionPolicy -ExecutionPolicy 'ByPass' -Scope 'Process' -Force -ErrorAction 'Stop' } Catch { }

## VerbosePreference Options: Stop, Inquire, Continue, SilentlyContinue
#  Set to Continue to see all Write-Verbose output
$VerbosePreference = 'SilentlyContinue'

## WarningPreference Options: Stop, Inqurie, Continue, SilentlyContinue
#  Set to Continue to see all Write-Warning output
$WarningPreference = 'SilentlyContinue'

## Set DCM compliance status to default value of 'Compliant'
[string]$DCM_Compliance_Status = 'Compliant'

## Definite certificate properties we are looking for
[string]$CertStoreName = 'Cert:\LocalMachine\My'
[string]$TemplateName = 'Company-802.1x-mach-auth-AE-v1.0'
[string]$CertIssuer = 'Company Internal Sub CA'

Try {
    ## Open the specified certificate store
    [boolean]$IsCertStoreOpen = $false
    Write-Verbose -Message "Open the certificate store [$CertStoreName]."
    [System.Security.Cryptography.X509Certificates.X509Store]$MyLocalMachineCertStore = Get-Item -Path $CertStoreName -ErrorAction 'Stop'
    [boolean]$IsCertStoreOpen = $true

    ## Open the certificate store in Read/Write mode so that we can delete the matching certificates from it.
    Write-Verbose -Message "Open the certificate store [$CertStoreName] in [ReadWrite] mode."
    $MyLocalMachineCertStore.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadWrite)

    ## Get list of certificates in certificate store
    Write-Verbose -Message "Get the list of certificates in the certificate store."
    [System.Security.Cryptography.X509Certificates.X509Certificate2[]]$MyLocalMachineCertificates = $MyLocalMachineCertStore.Certificates

    ## Delete certificates that match specified issuer and if they were created using the specified certificate template
    ForEach ($Cert in $MyLocalMachineCertificates) {
        Try {
            Write-Verbose -Message '---------------------------------------------------------------'
            Write-Verbose -Message "Discovered certificate with thumbprint [$($Cert.Thumbprint)]."

            ## Check to see if certificate matches specified certificate issuer
            [boolean]$IsCertMatchesIssuer = ($Cert.Issuer -cmatch $CertIssuer)
            If ($IsCertMatchesIssuer) {
                Write-Verbose -Message "Discovered certificate issuer [$($Cert.Issuer)] matches specified certificate issuer [$CertIssuer]."
            }
            Else {
                Write-Verbose -Message "Discovered certificate issuer [$($Cert.Issuer)] does not match specified certificate issuer [$CertIssuer]."
                Continue
            }


            ## Check to see if certificate matches specified certificate template
            [boolean]$IsCertMatchesTemplate = $false
            ForEach ($Extension in $Cert.Extensions) {
                #  Only check Format(0) against the name of the specified template if Oid.FriendlyName indicates this certificate was built from a template
                If ($Extension.Oid.FriendlyName -match 'Template' ){
                    Write-Verbose -Message 'Discovered certificate was built from a template.'
                    If ($Extension.Format(0) -match $TemplateName) {
                        Write-Verbose -Message "Discovered certificate was built from specified template [$TemplateName]."
                        [boolean]$IsCertMatchesTemplate = $true
                        Break
                    }
                    Else {
                        Write-Verbose -Message "Discovered certificate was not built from specified template [$TemplateName]."
                    }
                }
                Else {
                    Write-Verbose -Message 'Discovered certificate was not built from a template.'
                }
            }

            ## Check to see if we found a certificate that matches the specified issuer and was built with the specified template
            If ($IsCertMatchesIssuer -and $IsCertMatchesTemplate) {
                Write-Verbose -Message "Discovered certificate matches the specified issuer [$CertIssuer] and was built with the specified template [$TemplateName]."

                Try {
                    ## Delete the discovered certificate
                    #  Note: Remove-Item cmdlet does not support the certificate provider so the .Remove() method must be used to delete the cert
                    Write-Verbose -Message "Delete the discovered certificate with thumbprint [$($Cert.Thumbprint)]."
                    $null = $MyLocalMachineCertStore.Remove($Cert)

                    Write-Verbose -Message "Save the deleted certificate with thumbprint [$($Cert.Thumbprint)] for the deletion verification stage of the script."

                    [string[]]$RemovedCertificateThumbprints += $Cert.Thumbprint
                }
                Catch {
                    Write-Warning -Message ('{0}' -f $_.Exception.Message)

                    #  If we failed to remove the certificate, then the DCM is 'Not Compliant'
                    [string]$DCM_Compliance_Status = 'Not Compliant'
                }
            }

            #  Reset the state of the X509Certificate2 object
            $null = $Cert.Reset()
        }
        Catch {
            Write-Warning -Message ('{0}' -f $_.Exception.Message)
            [string]$DCM_Compliance_Status = 'Not Compliant'
            Continue
        }
    }
}
Catch {
    Write-Warning -Message ('{0}' -f $_.Exception.Message)

    [string]$DCM_Compliance_Status = 'Not Compliant'
    Write-Output -InputObject ($DCM_Compliance_Status)
    Exit
}
Finally {
    Try {
        If ($MyLocalMachineCertificates) {
            $null = $MyLocalMachineCertificates.Reset()
        }
        If ($IsCertStoreOpen) {
            $null = $MyLocalMachineCertStore.Close()
        }
    }
    Catch { }
}

Write-Verbose -Message '_______________________________________________________________'
Write-Verbose -Message '_______________________________________________________________'

## Verify that the certificates we wanted to delete have been deleted from the certificate store by filtering for those matching the thumbprint of the deleted certificate
If ($RemovedCertificateThumbprints) {
    Write-Verbose -Message 'Certificates with the matching specified criteria were discovered on this machine. Executing steps to verify that matching certificates were deleted.'

    Try {
        ## Open the specified certificate store
        [boolean]$IsCertStoreOpen = $false
        Write-Verbose -Message "Open the certificate store [$CertStoreName]."
        [System.Security.Cryptography.X509Certificates.X509Store]$MyLocalMachineCertStore = Get-Item -Path $CertStoreName -ErrorAction 'Stop'
        [boolean]$IsCertStoreOpen = $true

        ## Open the certificate store in Ready Only mode so that we can verify if targeted certificates were deleted.
        Write-Verbose -Message "Open the certificate store [$CertStoreName] in [ReadOnly] mode."
        $MyLocalMachineCertStore.Open([System.Security.Cryptography.X509Certificates.OpenFlags]::ReadOnly)

        ## Get list of certificates in certificate store
        Write-Verbose -Message "Get the list of certificates in the certificate store."
        [System.Security.Cryptography.X509Certificates.X509Certificate2[]]$MyLocalMachineCertificates = $MyLocalMachineCertStore.Certificates

        ## Verify that matching certificates were deleted from the certificate store
        ForEach ($RemovedCertThumbprint in $RemovedCertificateThumbprints) {
            Try {
                If ($MyLocalMachineCertificates.Thumbprint -contains $RemovedCertThumbprint) {
                    Write-Warning -Message "Certificate with thumbprint [$RemovedCertThumbprint] was not successfully deleted from certificate store [$CertStoreName]."
                    #  We failed to remove the certificate from the certificate store. The machine is not compliant.
                    [string]$DCM_Compliance_Status = 'Not Compliant'
                }
                Else {
                    Write-Verbose -Message "Certificate with thumbprint [$RemovedCertThumbprint] was successfully deleted from certificate store [$CertStoreName]."
                }
            }
            Catch {
                Write-Warning -Message ('{0}' -f $_.Exception.Message)
                [string]$DCM_Compliance_Status = 'Not Compliant'
                Continue
            }
        }
    }
    Catch {
        Write-Warning -Message ('{0}' -f $_.Exception.Message)
        [string]$DCM_Compliance_Status = 'Not Compliant'
    }
    Finally {
        Try {
            If ($MyLocalMachineCertificates) {
                $null = $MyLocalMachineCertificates.Reset()
            }
            If ($IsCertStoreOpen) {
                $null = $MyLocalMachineCertStore.Close()
            }
        }
        Catch { }
    }
}
Else {
    Write-Verbose -Message "No 802.1x UniCERT certificates were discovered in the certificate store [$CertStoreName] on this machine. Skipping steps to verify that appropriate certificates were deleted."
}


## Write out the compliance status
Write-Output -InputObject ($DCM_Compliance_Status)