【问题标题】:Powershell "Provider execution stopped because the provider does not support this operation."Powershell“提供程序执行已停止,因为提供程序不支持此操作。”
【发布时间】:2019-01-01 14:45:18
【问题描述】:

我正在尝试编写一个脚本来通过 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 
                }           
         }    
     }
  }

【问题讨论】:

  • 哪一行出现错误?
  • 这意味着您正在使用 PowerShell 2。Remove-Item 在 PowerShell 3 之前不适用于 cert: 提供程序。从这里的 cmets - stackoverflow.com/a/37229338/478656 - 和这里的文档 - @ 987654322@。您已标记此 Powershell v4,但您的远程服务器可能仅在 v2 上?
  • 运行Invoke-Command -Computername <server> -Scriptblock {$PSVersionTable.psversion}检查远程服务器的powershell版本
  • @TessellatingHeckler 你是对的。远程服务器正在使用 PSv2。本地服务器正在运行 PSv4。感谢您提供 PSv2 脚本。我越来越近了,但仍然需要一些帮助。我目前收到以下错误:详细:打开证书存储 [Cert:\LocalMachine\My]。详细:在 [ReadWrite] 中打开证书存储 [Cert:\LocalMachine\My] 详细:获取证书存储中的证书列表。详细:发现带有 FriendlyName [*.me.com] 的证书。
  • 也感谢@Drew。返回消息从先前的评论 VERBOSE 继续:发现的证书 FriendlyName [*.me.com] 与指定的证书友好名称 [cert.you.org] 不匹配。详细:在此计算机上的证书存储区 [Cert:\LocalMachine\My] 中未发现 802.1x UniCERT 证书。跳过步骤以验证是否删除了相应的证书。

标签: powershell powershell-4.0 powershell-provider


【解决方案1】:

以下是如何在 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)

【讨论】:

  • 似乎 [System.Security.Cryptography.X509Certificates.X509Store]$MyLocalMachineCertStore 需要更改以匹配我认为的 PKCS 证书。所以像 [System.Security.Cryptography.PKCS.????]$MyLocalMachineCertStore 但我不知道要填写什么类。
  • X509 存储参考将保持不变。您需要弄清楚如何从本地计算机上的 x509 证书存储中发现您希望删除的 PKCS 证书。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-18
  • 2012-12-24
  • 2020-01-09
  • 1970-01-01
相关资源
最近更新 更多