Gå til innhold

Finne ut om et spesifikt rotsertifikat er installert på klientmaskiner


Anbefalte innlegg

Jeg har tenkt til å sjekke om et spesifikt rotsertifikat er installert på diverse klientmaskiner i et nettverk. Jeg har funnet et script i PowerShell som gjør at en kan sjekke dette på maskinen en sitter på, men er det noen som vet om noen systemer eller script som gjør dette på en forholdsvis enkel måte?

Lenke til kommentar
Videoannonse
Annonse

Dette kan løses vha understående kommando i PowerShell men jeg er usikker på hvordan man kan få kjørt dette i bakgrunnen på maskiner i et nettverk. En kan vel pipe ut svaret for maskinene detet gjelder for. 

Get-ChildItem -Path cert:\ -DNSName "*DSDTestProvider*" > sti til fil som dumpes ut i tilfelle treff
Endret av ilpostino
Lenke til kommentar

 

Dette kan løses vha understående kommando i PowerShell men jeg er usikker på hvordan man kan få kjørt dette i bakgrunnen på maskiner i et nettverk. En kan vel pipe ut svaret for maskinene detet gjelder for. 

 

Get-ChildItem -Path cert:\ -DNSName "*DSDTestProvider*" > sti til fil som dumpes ut i tilfelle treff

Invoke-Command burde vel gjøre nytten...

 

Se nærmere på http://powershell.org/wp/forums/topic/running-get-childitem-on-remote-server-to-check-file-versions/#post-14505

 

Ellers bør du antakelig kjøre følgende cmdlet også:

Import-Module Microsoft.PowerShell.Security

samt at det er verdt å merke seg at Get-ChildItem kan ta switchen -Recurse...

 

Edit: Viktig at maskinene du skal hente info fra har PSRemoting aktivert, helst via GPO, evt. må du kjøre Enable-PSRemoting i PowerShell på hver enkelt maskin...

Endret av k-ryeng
Lenke til kommentar

Er intensjonen her at du skal installere det på de maskinene som eventuelt ikke har det?

 

Jeg vil i så fall foreslå at du bruker GPO til å installere det automatisk via:

Computer Configuration -> Policies -> Windows Settings -> Security Settings -> Public Key Policies -> Truested Root Certification Authority -> Import Certificate Wizard.

 

Det gir kanskje ikke noe feedback på hvilke maskiner som hadde det fra før, men du bør kunne være rimelig trygg på at alle maskiner har det etterpå.

Lenke til kommentar

Er intensjonen her at du skal installere det på de maskinene som eventuelt ikke har det?

 

Jeg vil i så fall foreslå at du bruker GPO til å installere det automatisk via:

Computer Configuration -> Policies -> Windows Settings -> Security Settings -> Public Key Policies -> Truested Root Certification Authority -> Import Certificate Wizard.

 

Det gir kanskje ikke noe feedback på hvilke maskiner som hadde det fra før, men du bør kunne være rimelig trygg på at alle maskiner har det etterpå.

 

Jeg skal dobbelsjekke om et digitalt sertifikat er installert. Er det det skal det slettes. Hvis ikke skal ingen ting gjøres. 

Lenke til kommentar
  • 5 uker senere...

Ser at tråden er litt gammel, så antar at du alt har løst dette.

 

Men skrev ett kjapt eksempel på hvordan dette kan løses med powershell, sånn om noen andre skulle lure. 
Koden er ikke testet, men koden er rimelig rett frem, så bør ikke være store fallgruvene her :)

Bør være rimelig enkelt å legge til ønsket funksjonalitet (fjerne cert om det finnes). 

#Cert to find
[String]$Cert = "*Nvidia*"
#List of computers to check
[Array]$Computers = "Client1","Client2"


foreach ($Computer in $Computers) {

    $CertTest = Invoke-Command  -Scriptblock { param($Cert)
        $Certs = Get-ChildItem -Path cert:\ -DNSName $Cert -Recurse 
	    if ($certs) {
	        $ReturnResult = @{ 'Result'       = 'Error' ;
                                'ThumbPrints'  = $certs.thumbprint 
                                'ComputerName' = $(Hostname)}	
        } else {
		    $ReturnResult = @{ 'Result'       = 'Success' ;
                                'ComputerName' = $(Hostname) }
	    }
       # Convert the result of the command to JSON. JSON is easier for parsing.
        Return (ConvertTo-Json $ReturnResult)
    } -Args $Cert -ComputerName $Computer

    #Convert the result from JSON
    $CertTestResult = (ConvertFrom-Json $CertTest)

    If ($CertTestResult.result -eq "Success") {
	    Write-Output "$($CertTestResult.ComputerName) does not have $cert installed"
    } else {
	    Write-Output "$($CertTestResult.ComputerName) have the following certificates installed: $($CertTEstResult.ThumbPrints)"
    }
}
Endret av mreinha
Lenke til kommentar

Ser at tråden er litt gammel, så antar at du alt har løst dette.

 

Jeg holder på å se meg igjennom haugevis av webcasts/opplæringsvideoer på Microsoft Virtual Academy med PowerShell for å lære mer avanserte funksjoner i PowerShell. Dette er en veldig stor hjelp i riktig retning. Takk for hjelpen. 

Lenke til kommentar

Om du beskriver ønsket funksjonalitet i litt detaljer, så kan jeg helt sikkert skrive det ferdig for deg i kveld :)

Hva er ønsket funksjonalitet?

Finne Cert X? Slette Cert X? Hva er input kilden din? Hente computer objekter fra AD?

Er winrm enablet? Fungerer kerberos? Om du har Trust mellom to domener, så må det være forest trust om Kerberos skal fungere. Vi kan dog anta at Kerberos ikke fungerer, og helle anta at vi trenger credentials. 

Lenke til kommentar

Planen er å se om et cert er installert på maskinkontoer som gjerne hentes fra AD. Finnes det kan det gjerne slettes med en gang men det kunne kanskje være greit om det dukker opp en eller annen statistikk på hvor mange eller hvilke maskiner certifikatet ble funnet på men det er ikke et must. 

 

Jeg enablet WINRM via GP her for et par uker siden så det fungerer. Alt er i samme domene. 

Lenke til kommentar

Funksjonen Invoke-RemoveCertificate bør fungere. Tok en kjapp test i en VirtualLab hos MS, og det gikk fint.

 

Kjapp forklaring:

Funksjonen bør returnere en av fire status for hvert SertifikatSerialNumber du gir som input:

- Success (Cert er slettet)

- Found (funnet, ikke slettet). 

​- Error (Med errormessage om at sletting feilet)

- Failed (Ikke funnet cert)

 

Du kan angi flere ComputerName som input param. Du kan også angi flere CertificateSerialNumbers som input. Du kan fks pipe get-adcomputer til funksjonen slik som dette:

get-adcomputer *jadi* | select name | Invoke-RemoveCertificate -CertificateSerialNumbers "02AC5C266A0B409B8F0B79F2AE462577" 

 

Eksempler:

 

.Example
Report on a specific cert on localhost
Invoke-RemoveCertificate -ComputerName "localhost" -CertificateSerialNumbers "02AC5C266A0B409B8F0B79F2AE462577"
 .Example
Remove a specific cert from localhost
Invoke-RemoveCertificate -ComputerName "localhost" -CertificateSerialNumbers "02AC5C266A0B409B8F0B79F2AE462577" -RemoveCertificate $true
 
Merk, jeg har ikke gjort noe særlig med testing av dette, så det kan finnes en bug eller to. Selve invoke-command delen, og da særlig biten som verifiserer dette er dog godt testet i mange andre script. Jeg er dog usikker på om det er særlig lurt å søke etter fks ett sertifikats serialnumber og slette cert basert på bare det. Så her kan det hende at du bør legge på ett bedre filter før man faktisk sletter ett sertifikat (linje 125).
 
Ellers, det returneres ett object fra funksjonen som inneholder følgende:
-Name: Navn på server
- IsOnline: Fikk vi kontakt med serveren? Yes or No
-SessionDisconnected: Klarte vi å koble ned sesjonen vår når vi var ferdig? Yes or no. 
-RemovalResult: Dette er faktisk enda ett customobject inne i ett customobject. Her finner du dog resultat av fjerningen av sertifikatene du ønsket å få fjernet. Status er som beskrevet over. Eventuelle feilmeldinger vil du også finne her.
post-170816-0-96367600-1451519675_thumb.png
 
 
Jeg tar IKKE ansvar for eventuell skade som måtte oppstå i ditt nettverk. Jeg anbefaler deg på det sterkeste å bedre filtrering av hvilket sertifikat som skal slettes før du bruker funksjonen. Utover det, lykke til, og velkommen til en fantastisk mye bedre hverdag med hjelp av powershell :)
 
Function Invoke-RemoveCertificate {
	<#  
	.SYNOPSIS  
		Connect to remote computer and removes a specified certificate
	.DESCRIPTION  
		This scripts connectes to a remote computer using invoke-command. It will check for specific certificates and remove them. The result is returned as a PS custom object.
	.Parameter  Computername
		List of computers to run the tests against. Both FQDN and netbios names are supported
	.Parameter CertificateSerialNumber
		List of certificate SerialNumbers
	.Parameter RemoveCertificate
		If specified, any certificate in the CertificateSerialNumber list will be removed
	.Parameter Credentials
		Credentials. Needed when there is no trust, DNS issues, kerberoes issues and so on. 
	.Example
		Report on a specific cert on localhost
		Invoke-RemoveCertificate -ComputerName "localhost" -CertificateSerialNumbers "02AC5C266A0B409B8F0B79F2AE462577"
    .Example
		Remove a specific cert from localhost
		Invoke-RemoveCertificate -ComputerName "localhost" -CertificateSerialNumbers "02AC5C266A0B409B8F0B79F2AE462577" -RemoveCertificate $true
	.NOTES  
		File Name		: Invoke-RemoveCertificate.ps1
		Author			: 
		Prerequisite	: PowerShell V4 and winrm must be configured on the server running this script
	
	#>

Param (
	[Parameter(Position=0,Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)]
	[Alias("DNSHostName")]
	[Alias("Name")]
	[ValidateNotNullOrEmpty()]
	[string[]] $ComputerName,
	[Parameter(Position=1,Mandatory=$True)]
	[ValidateNotNullOrEmpty()]
	[Array] $CertificateSerialNumbers,
	[Parameter(Position=2, Mandatory=$false)]
	[ValidateNotNullOrEmpty()]
	[bool] $RemoveCertificate = $False,
	[Parameter(Position=3,Mandatory=$false)]
	[System.Management.Automation.PSCredential]
	[System.Management.Automation.Credential()] $Credentials = [System.Management.Automation.PSCredential]::Empty
	
)
Begin { 
	#
}
Process{	
	Foreach ($Server in $ComputerName) {
		#ServerIsOnline is used to verify that we can reach the server. We will skip a lot of tests if this variable is set to false at any point
		[bool]$ServerIsOnline = $True
		#ServerIsDisconnected indicates if we manage to close the ps session. This is acutally important. 
		[bool]$ServerIsDisconnected = $True
		#Create the ReturnResults PSObject
		$ReturnResults = @()
		
		#region Basic tests to verify we can reach the computer
		#If the provided servername does match a netbios name, try to resolve the DNS name
            if ($Server -Match "^([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])$") {
			    #Get FQDN of the server
			    try {
				    $server = Resolve-DnsName $Server -ea Stop  -type a | select -first 1 | select -ExpandProperty Name
			    }
			    #Warn about any failures
			    catch {
				    Write-Warning "Unable to resolve DNS name for server: $Server."
				    Write-Verbose "Unable to resolve DNS name for server: $Server. Error: $_"
				    $ServerIsOnline = $False
			    }
            }

			#Check that we can reach the server
			if ($ServerIsOnline) {
				try {
					Test-Connection -ComputerName $Server -count 1 -EA stop | Out-Null
				}
				#Warn about any failures
				Catch {
					Write-Warning "Unable to test connection to server: $server."
					Write-Verbose "Unable to test connection to server: $server. Error: $_"
					$ServerIsOnline = $False
				}
			}

			#Connect to the server
			if ($ServerIsOnline) {
				#If credentials where provided, use them
				if ($Credentials.UserName) {
					try {
						$Session = New-PSSession -ComputerName $Server -Credential $Credentials -ErrorAction Stop
					} 
					#Warn about any failures
					catch { 
						Write-Warning "Unable to create a new PSSession against server: $Server using the provided credentials: $($Credentials.UserName)."
						Write-Verbose "Unable to create a new PSSession against server: $Server using the provided credentials: $($Credentials.UserName). Error: $_"
						$ServerIsOnline = $False
					}
				#If no credentials where provided, use the default authentication
				} else {
					try {
						$Session = New-PSSession -ComputerName $Server -Authentication Default -ErrorAction Stop
					} 
					#Warn about any failures
					catch { 
						Write-Warning "Unable to create a new PSSession against server: $Server."
						Write-Verbose "Unable to create a new PSSession against server: $Server. Error: $_"
						$ServerIsOnline = $False
					}
				}
			}
			#endregion Basic tests to verify we can reach the computer
			
			#region connect to server and perform an action
			#If the server is online, run the test
			if ($ServerIsOnline) {
				#Invoke command the test by connecting the session we created earlier on.
				Try {
					$RemovalResults = Invoke-Command -Session $session -ScriptBlock {param($CertificateSerialNumbers, $RemoveCertificate)
	
						$TestResults = @()
						#Foreach of the cert thumbprints
						Foreach ($CertificateSerialNumber in $CertificateSerialNumbers) {
							#Get the certificate
							$Certs = Get-ChildItem -Path cert:\ -Recurse | where {$_.SerialNumber -eq $CertificateSerialNumber}
							#If we found any certs
							if ($Certs ) {
								#If we want to remove the cert
								if ($RemoveCertificate) {
										#Remove the certificate
										Try {
											Remove-Item $Cert.PsPath -DeleteKey
										} catch {
											$Failed = $True
											$ErrorMessage += "Unable to remove certificate: $CertificateSerialNumber. Error: $_"
										}
										
										#If we failed to remove the cert
										If ($Failed) {
											$Properties = @{ Result    =  'Error'; 
															 Certs		   =  $CertificateSerialNumber ; 
															ErrorMessage   =  $ErrorMessage} 
											$Newobject = New-Object PSObject -Property $Properties 
											#Add the results to test results
											$TestResults += $Newobject
										#If we succeeded
										} else {
											$Properties = @{ Result    =  'Success';
															 Certs		   =  $CertificateSerialNumber ; 
															 ErrorMessage  =  $ErrorMessage} 
											$Newobject = New-Object PSObject -Property $Properties 
											#Add the results to test results
											$TestResults += $Newobject	
										}
								#Found, but don't want to do anything
								} else {
									$Properties = @{ Result    =  'Found';
															 Certs		   =  $CertificateSerialNumber ; 
															 ErrorMessage  =  $ErrorMessage} 
									$Newobject = New-Object PSObject -Property $Properties 
									#Add the results to test results
									$TestResults += $Newobject	
								}
							} else {
								$Properties = @{ Result         =  'Failed' ;
												 Certs		    =  $CertificateSerialNumber ; 
												 ErrorMessage   =  "Unable to find certificate: $CertificateSerialNumber"}
								$Newobject = New-Object PSObject -Property $Properties 
								#Add the results to test results
								$TestResults += $Newobject
							}
							
						}

					Return $TestResults

				} -EA SilentyContinue -ArgumentList $CertificateSerialNumbers, $RemoveCertificate
				#Something unexpected happend
				} catch {
					$RemovalResults = "Unexpected error occurred during the test."
					Write-Verbose "Unexpected error occurred during the test. Error: $_"
				}
			#Else set the test result to false. This must be done, because if the first server is not online, the psobject will miss important fields.
			} else {
				$RemovalResults = $false
			} 
			
					
			# if the server is online, remove the PSSession
			if ($ServerIsOnline) {
				#Disconnect the server
				try {
					Remove-PSSession -Session $Session | out-null
					$SessionDisconnected = $True
					}
				#Warn about any failures
				catch { 
					Write-Warning "Unable to remove PSSession against server: $Server."
					Write-Verbose "Unable to remove PSSession against server: $Server. Error: $_"
					$SessionDisconnected = $false
				}
			}
			
			#endregion connect to server and perform an action
			
			#Build the final results
			#Create the output using a PS object
			$FinalResult = New-Object PSObject

			#Always add the servername as name property
			Add-Member -InputObject $FinalResult -MemberType NoteProperty -Name Name -Value $Server
			Add-Member -InputObject $FinalResult -MemberType NoteProperty -Name IsOnline -Value $ServerIsOnline
			Add-Member -InputObject $FinalResult -MemberType NoteProperty -Name SessionDisconnected -Value $SessionDisconnected
			Add-Member -InputObject $FinalResult -MemberType NoteProperty -Name RemovalResults -Value $RemovalResults
			
			
			#Write Output
			Write-Output $FinalResult
		
		} #end foreach
	} # End process
}
Endret av mreinha
Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...