Powershell Certificate Extensions export-csv - csv

I'm trying to gather certificate extensions into a csv. The PowerShell commands seem to display just fine within PowerShell but when piped to a csv they display other types of data?
$cert = Get-ChildItem cert:\localmachine -Recurse
($cert.Extensions | Where-Object {$_.Oid.FriendlyName -eq "Key Usage"}).Format(1) | Export-Csv C:\Folder\File.csv
After searching the web I tried something different but still was unable to get the data to get captured and displayed as it does within PowerShell.
$cert=Get-ChildItem cert:\localmachine -Recurse
$sanExt=$cert.Extensions | Where-Object {$_.Oid.FriendlyName -match "subject alternative name"}
$sanObjs = new-object -ComObject X509Enrollment.CX509ExtensionAlternativeNames
$altNamesStr=[System.Convert]::ToBase64String($sanExt.RawData)
$sanObjs.InitializeDecode(1, $altNamesStr)
Foreach ($SAN in $sanObjs.AlternativeNames) {$SAN.strValue}
$sanExt.Format(1) | Export-Csv C:\Folder\File.csv

For others looking to also gather the extension fields, this was my resolution:
$cert = Get-ChildItem cert:\localmachine -Recurse
($cert.Extensions | Where-Object {$_.Oid.FriendlyName -eq "Key Usage"}).Format(1) |
Select-Object -Property #{Name="Certificate";Expression={$_}} |
Export-csv -Path C:\Folder\file.csv`

Related

Powershell ConvertFrom-Json accessing json value

I have a json file that I'd like to convert to csv. However, the actual value is nested inside reading key that I need to access. It returns System.Object[] in which I know I have to access this, but I don't know how.
the following is the result.json file,
{"totalNumberOfReadings":1488,
"readings":
[
{"meterNumber":"xxxxx","date":"2022-02-01 00:00","reading":0.0,"status":"AsRequested"},
{"meterNumber":"xxxxx","date":"2022-01-31 23:30","reading":0.0,"status":"As Requested"},
{"meterNumber":"xxxxx","date":"2022-01-31 23:00","reading":0.0,"status":"As Requested"},
{"meterNumber":"xxxxx","date":"2022-01-31 23:00","reading":0.0,"status":"As Requested"},
]
}
My script is like this
C:\> (Get-Content -Raw result.json | ConvertFrom-Json) | ConvertTo-Csv -NoTypeInformation
the output is this
"totalNumberOfReadings","readings"
"1488","System.Object[]"
This is just the summary/metadata. I want the actual content inside the key's value, how to access the value?
Either use member access:
(Get-Content -Raw result.json | ConvertFrom-Json).readings | ConvertTo-Csv -NoTypeInformation
...or only pipeline commands:
Get-Content -Raw result.json | ConvertFrom-Json | ForEach-Object readings | ConvertTo-Csv -NoTypeInformation
ForEach-Object readings is the short form of ForEach-Object -MemberName readings.

Powershell - Reading multiple json files in a directory and output the data

I'm having to whip up a process that will read multiple json files created by another process.
I have code that can read a single file, but we're needing to process these results in bulk.
Here's my current code:
$json = Get-ChildItem $filePath -recurse | Where-Object { $_.LastWriteTime -gt [DateTime] $filesNewerThan } | ConvertFrom-Json
$json.delegates | foreach-Object {
foreach ($File in $_.files)
{
[PSCustomObject]#{
LastName = $_.lastName
ZipCode = $File.zipCode
BirthDate = $File.birthdate
Address = $File.Address}
}
}
Right now I'm getting an error about an "invalid JSON primitive" which what I'm guessing is an issue where I don't have "Get-Content" specified in my code.
Wondering what my issue is with my code.
ConvertFrom-Json currently (as of PowerShell 7.0) doesn't support file-path input, only file-content input (the actual JSON string), which means that you need to involve Get-Content:
$json = Get-ChildItem -File $filePath -Recurse |
Where-Object { $_.LastWriteTime -gt [DateTime] $filesNewerThan } |
ForEach-Object { Get-Content -Raw -LiteralPath $_.FullName | ConvertFrom-Json }

How can i uninstall Google Chrome using Power Shell

I am working towards writing a powershell script for uninstalling the current version 54.0.2840.99 m of Google Chrome from my machine but could not be able to do so. I am using the following piece of code in my script:
$app = Get-WmiObject -Class Win32_Product | Where-Object {
$_.Name -match “Google Chrome”}
$app.Uninstall()
The chrome is installed in my machine but the above code is not showing Google Chrome in the list. It is returning null value and it could not be able to uninstall.
Could you please tell me where i have been went wrong or any other alternative solution for uninstalling the Google Chrome via PowerShell?
Google Chrome doesn't use WMI when installing chrome. You can use the command below to find the version, and uninstall chrome using its setup package.
(Get-ItemProperty -path 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Google Chrome').version | ForEach-Object {& ${env:ProgramFiles(x86)}\Google\Chrome\Application\$_\Installer\setup.exe --uninstall --multi-install --chrome --system-level --force-uninstall}
I use this:
$GoogleChrome = [CimInstance](Get-CimInstance -ClassName Win32_Product | Where-Object {$_.Name -eq 'Google Chrome'})
If ($GoogleChrome -ne $null) {
Write-Host 'Uninstalling Google Chrome'$GoogleChrome.Version
Invoke-CimMethod -InputObject $GoogleChrome -MethodName 'Uninstall' | Out-Null
}
The search for the uninstaller takes longer than I would like, but it works for the 64-bit version of Google Chrome we use.
There might have been some changes with Chrome that gave me some trouble with the solutions above. This worked for me just recently, and it will work with some other software packages too. It also gives a good basis for confirming the package is no longer installed:
$target_computers='computer1','computer2','computer3'
$software_to_remove='chrome'
Get-PSSession | Remove-PSSession
$target_sessions=New-PSSession -ComputerName $target_computers
if ($software_to_remove -Like 'chrome') {
Invoke-Command -Session (Get-PSSession) -ScriptBlock{
$computer_name=$env:COMPUTERNAME
$chrome_installed_object=(Get-ItemProperty -path 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\Google Chrome')
if ($chrome_installed_object -ne $null) {
$chrome_version=($chrome_installed_object | select-object -ExpandProperty Version)
$chrome_uninstaller_string=($chrome_installed_object | Select-Object -ExpandProperty UninstallString)
$chrome_uninstaller_full_string=($chrome_uninstaller_string+" --force-uninstall")
Write-Host "For $computer_name, we have found the following version of Chrome: $chrome_version"
Write-Host "Removing version $chrome_version"
Write-Host "This is the Chrome uninstall string we are using: $chrome_uninstaller_full_string"
cmd.exe /c $chrome_uninstaller_full_string
}
}
}
Invoke-Command -Session (Get-PSSession) -ScriptBlock{
param($software_to_remove)
$computer_name=$env:Computername
#Look at installed programs
Write-Host ("Looking for a package matching this pattern: "+$software_to_remove+" on server "+$computer_name)
$program_to_remove = $(Get-WmiObject -Class Win32_Product | Where-Object -Property Name -Like "*$software_to_remove*")
if (![string]::IsNullOrWhiteSpace($program_to_remove)) {
Write-Host "These programs have been located: $program_to_remove"
$oktoremove=$(Read-Host "OK to remove these programs (y or n)?")
If (!($oktoremove -eq 'y')) {
Write-Host 'Exiting the entire script on server $computer_name since you do not wish to take any further action now'
exit
}
$program_to_remove.Uninstall()
}
#Look at installed packages
$PackageToRemove=$(Get-Package -Provider Programs -IncludeWindowsInstaller | Where-Object -Property Name -Like "*$software_to_remove*")
$PackageToRemove_name=$(Get-Package -Provider Programs -IncludeWindowsInstaller | Where-Object -Property Name -Like "*$software_to_remove*" | Select-Object -ExpandProperty Name)
if (![string]::IsNullOrWhiteSpace($PackageToRemove)) {
Write-Host "$PackageToRemove_name"
$oktoremove=$(Read-Host "OK to remove software (y or n)?")
If (!($oktoremove -eq 'y')) {
Write-Host 'Exiting the entire script on server $computer_name since you do not wish to take any further action now'
exit
}
Uninstall-Package -Name $PackageToRemove -Verbose -Force
}
#Just in case the previous approach did not remove the package successfully, use the GUID this time
Get-Package -Provider Programs -IncludeWindowsInstaller | Where-Object -Property Name -Like "*$software_to_remove*" | Uninstall-Package
#Check again, just to make sure
$x86Path = "HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*"
$installedItemsX86 = Get-ItemProperty -Path $x86Path | Select-Object -Property PSChildName, DisplayName, DisplayVersion
$x64Path = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*"
$installedItemsX64 = Get-ItemProperty -Path $x64Path | Select-Object -Property PSChildName, DisplayName, DisplayVersion
$installedItems = $installedItemsX86 + $installedItemsX64
$installedItems | Where-Object -FilterScript { $null -ne $_.DisplayName } | Sort-Object -Property DisplayName | ft
} -ArgumentList($software_to_remove)

Issue in export Array to CSV file

I have list of machine in text file and I am trying to get the details of physical drives, OS architecture and physical memory. With the help of Matt (SO user) here is the powershell script.
$server = Get-Content .\Server.txt
#$infoObject11 = #{}
$infoObject11 = #{}
foreach ($server in $servers) {
# Gather all wmi drives query at once
$alldisksInfo = Get-WmiObject -Query "SELECT * FROM Win32_DiskDrive" -ComputerName $server -ErrorAction SilentlyContinue | Group-Object __Server
# Figure out the maximum number of disks
$MaximumDrives = $alldisksInfo | Measure-Object -Property Count -Maximum | Select-Object -ExpandProperty Maximum
# Build the objects, making empty properties for the drives that dont exist for each server where need be.
$server | ForEach-Object {
# Clean the hashtable
$infoObject1 = #{}
# Populate Server
$infoObject1.Server = $server
$HOSTNAME = Get-WMIObject -Query "Select * from Win32_OperatingSystem" -ComputerName $infoObject1.Server
# Add other simple properties here
$infoObject1.PhysicalMemory = (Get-WmiObject Win32_PhysicalMemory -ComputerName $infoObject1.Server | Measure-Object Capacity -Sum).Sum/1gb
$infoObject1.OSarchitecture =$HOSTNAME.osarchitecture
# Add the disks information from the $diskInfo Array
$serverDisksWMI = $alldisksInfo | Where-Object{$_.Name -eq $infoObject1.Server} | Select-Object -ExpandProperty Group
for ($diskIndex =0; $diskIndex -lt $MaximumDrives;$diskIndex++) {
$infoObject1."PhysicalDisk$diskIndex" = [Math]::Round(($serverDisksWMI | Where-Object{($_.DeviceID -replace "^\D*") -eq $diskIndex} | Select -Expand Size)/1GB)
}
}
# Create the custom object now.
New-Object -TypeName psobject -Property $infoObject1 | Export-Csv -path .\Server_Inventory_$((Get-Date).ToString('MM-dd-yyyy')).csv -NoTypeInformation
}
Problem is in the CSV file I am getting single machine details but in server.txt file there are more than 1 machine. If I print $infoObject1 before New-Object then I can see there are details of multiple machine. It seems like some issue with array and I am not able to export it in CSV.
Can anybody please suggest on this.
It looks like you are having issues integrating my code. You have added a second loop that should not be there. Also as other users pointed out you are not creating the per server object outside the loop. The answer, from where your code comes from, has that part correct. I had even showed you where to put the Export-CSV.
$servers = Get-Content .\Server.txt
# Gather all wmi drives query at once
$alldisksInfo = Get-WmiObject -Query "SELECT * FROM Win32_DiskDrive" -ComputerName $servers -ErrorAction SilentlyContinue | Group-Object __Server
# Figure out the maximum number of disks
$MaximumDrives = $alldisksInfo | Measure-Object -Property Count -Maximum | Select-Object -ExpandProperty Maximum
# Build the objects, making empty properties for the drives that dont exist for each server where need be.
$servers | ForEach-Object {
# Clean the hashtable
$infoObject1 = #{}
# Populate Server
$infoObject1.Server = $_
# Add other simple properties here
$infoObject1.PhysicalMemory = (Get-WmiObject Win32_PhysicalMemory -ComputerName $infoObject1.Server | Measure-Object Capacity -Sum | Select-Object -ExpandProperty Sum)/1GB
$infoObject1.OSarchitecture = Get-WMIObject -Query "Select * from Win32_OperatingSystem" -ComputerName $infoObject1.Server | Select-Object -ExpandProperty OSArchitecture
# Add the disks information from the $diskInfo Array
$serverDisksWMI = $alldisksInfo | Where-Object{$_.Name -eq $infoObject1.Server} | Select-Object -ExpandProperty Group
for ($diskIndex =0; $diskIndex -lt $MaximumDrives;$diskIndex++) {
$infoObject1."PhysicalDisk$diskIndex" = [Math]::Round(($serverDisksWMI | Where-Object{($_.DeviceID -replace "^\D*") -eq $diskIndex} | Select-Object -ExpandProperty Size)/1GB)
}
# Create the custom object now for this pass in the loop.
New-Object -TypeName psobject -Property $infoObject1
} | Export-Csv -path .\Server_Inventory_$((Get-Date).ToString('MM-dd-yyyy')).csv -NoTypeInformation
foreach ($server in $servers) {
...
New-Object -TypeName PSObject -Property $infoObject1 |
Export-Csv -Path .\Server_Inventory_$((Get-Date).ToString('MM-dd-yyyy')).csv -NoTypeInformation
}
You're exporting inside the loop without using the parameter -Append (available in PowerShell v3 and newer). That overwrites your output file with each iteration, leaving you with just the data of the last server.
Either use the parameter -Append (if you have PowerShell v3 or newer):
foreach ($server in $servers) {
...
New-Object -TypeName PSObject -Property $infoObject1 |
Export-Csv -Append -Path .\Server_Inventory_$((Get-Date).ToString('MM-dd-yyyy')).csv -NoTypeInformation
}
or move Export-Csv outside the loop (works with all PowerShell versions):
(foreach ($server in $servers) {
...
New-Object -TypeName PSObject -Property $infoObject1
}) | Export-Csv -Path .\Server_Inventory_$((Get-Date).ToString('MM-dd-yyyy')).csv -NoTypeInformation
Note that you need to run the loop in parentheses for this to work, as foreach loops don't output to the pipeline.
You could also replace the foreach loop with ForEach-Object if you want to feed the pipeline directly:
Get-Content .\Server.txt | ForEach-Object {
$server = $_
...
New-Object -TypeName PSObject -Property $infoObject1
} | Export-Csv -Path .\Server_Inventory_$((Get-Date).ToString('MM-dd-yyyy')).csv -NoTypeInformation

Include file owner to powershell pipe

I've got a script which works fine which lists all files modified since last 7 days and want to modify it to add file owner to the export csv file.
$dir_to_look="F:\"
$month_backdate=$(Get-Date).AddDays(-7)
Get-Childitem $dir_to_look -Recurse | ? { !($_.psiscontainer) -and $_.LastWriteTime -gt $month_backdate } | ForEach-Object {Get-Acl $_.FullName}.owner | Select-object LastWriteTime, Directory, FullName | export-csv -path \\sharename\report.csv -encoding "unicode"
But not sure how to correctly add get-acl to the pipe as currently it prints nothing to my report file
Your Foreach-Object command should be:
... | Foreach-Object {Add-Member -Input $_ -Type NoteProperty -Name Owner -Value (Get-Acl $_.Fullname).Owner -PassThru} | Select-object LastWriteTime, Directory, FullName, Owner | ...
Add-Member is handy for adding properties (and methods) to objects.
Use a hash table with Select-Object.
$dir_to_look="F:\"
$month_backdate=$(Get-Date).AddDays(-7)
Get-Childitem $dir_to_look -Recurse | ? { !($_.psiscontainer) -and $_.LastWriteTime -gt $month_backdate } |
Select-object LastWriteTime, Directory, FullName, #{n='Owner';e={(Get-ACL $_.FullName).owner}}
$dir_to_look="F:\"
$month_backdate=$(Get-Date).AddDays(-7)
Get-Childitem $dir_to_look -Recurse | ? { !($_.psiscontainer) -and $_.LastWriteTime -gt $month_backdate } |
Select-object LastWriteTime, Directory, FullName, #{n='Owner';e={(Get-ACL $_.FullName).owner}}