Powershell“由于提供程序不支持此操作,因此停止了提供程序的执行。”

时间:2018-07-24 21:24:41

标签: powershell powershell-v4.0 powershell-provider

我正在尝试编写一个脚本,以通过FriendlyName检查远程服务器上的证书。返回此证书后,我要确认已删除此证书。 当前,下面的代码返回“由于提供者不支持此操作,所以提供者执行已停止”。为什么提供程序在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 
                }           
         }    
     }
  }

1 个答案:

答案 0 :(得分:0)

这是一个如何在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)