Output of installed programs with CSV-Export
I have a couple of problems getting out and exporting my current project. I use a cmdlet Get-RemoteProgram
to get installed software over the network and registry entries.
This is my code:
function Get-RemoteProgram ....
$computername = Import-Csv "C:\data\test\test.csv" |
select -ExpandProperty PCName
$regex = @("Program1|Program2|Program3")
$items = @()
foreach ($computer in $computername) {
if (Test-Connection $computer -ErrorAction SilentlyContinue -Count 1) {
$query = Get-RemoteProgram -ComputerName $computer -Property DisplayVersion |
where {$_.ProgramName -match $regex}
$obj = New-Object -Type PSObject
$obj | Add-Member -Name ("Computername") -Value $computer -MemberType NoteProperty -Force
$maxcount = $query.ProgramName.Count
if ($maxcount -gt 1) {
for ($i=0; $i -lt $maxcount; $i++) {
$progandversion = $query.ProgramName[$i] + $query.DisplayVersion[$i]
$obj | Add-Member -Name ($progandversion) -Value "Available" -MemberType NoteProperty -Force
}
} elseif ($maxcount -eq 1) {
$progandversion = $query.ProgramName + $query.DisplayVersion
$obj | Add-Member -Name ($progandversion) -Value "Available" -MemberType NoteProperty -Force
}
$obj | Add-Member -Name ("ProgrammVersion$i") -Value $query.DisplayVersion[$i] -MemberType NoteProperty -Force
$items += $obj
}
$items | Export-Csv c:\daten\inventur\output_final.csv -Append -Force
Write-Host "$computer has been checked.."
}
The problem I am currently having is that my script does not list all the different programs that I am looking for. It should export the username and then - on the same line - release available if the software is installed, or keep it clean if the program was not found.
What I am getting right now:
#TYPE System.Management.Automation.PSCustomObject Computername, "Program1", "Program2" Computer1, "Available", "Available" Computer1, "Available", "Available" Computer2 ,, Computer1, "Available", "Available" Computer3 ,, Computer2 ,, Computer1, "Available", "Available"
I don't know why computers are taken out multiple times.
I would like it to be like this:
Computername, Program1, Program2, Program3, Program4 Computer1, Available ,, Available ,, Computer2, Available ,,,, Computer3 ,,, Available, Computer4 ,,,,
Can you help me somehow?
source to share
Your problem is twofold. First, you want to update the existing data in CSV, but you use -Append
at startup instead Export-CSV
. This explains that there is more than one line with the given one ComputerName
. Second, you are not setting default values ββfor the given ProgramName
, and therefore no properties for programs that are not found anywhere in the CSV output. To solve your first problem, you need to run Export-CSV
without adding to save the entire dataset to a CSV file. And to solve the second problem, you must pre-populate your new properties PSObject
. The preparation should be done as follows:
$programs=get-content "programs.txt" # one name one line, or an array of names in @()
$regex='('+($programs -join ',')+')' # regex out of array
Then in your main loop, you add this line after the call New-Object
:
$programs | % { $obj | Add-Member -Name $_ -Value "Not found" -MemberType NoteProperty } # create default values
Have to do. Swap "Not Found" for an empty string if you want.
source to share
Encoded version in c # of installed programs via windows registry
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
namespace SoftwareInventory
{
class Program
{
static void Main(string[] args)
{
//!!!!! Must be launched with a domain administrator user!!!!!
Console.ForegroundColor = ConsoleColor.Green;
StringBuilder sbOutFile = new StringBuilder();
Console.WriteLine("DisplayName;IdentifyingNumber");
sbOutFile.AppendLine("Machine;DisplayName;Version");
//Retrieve machine name from the file :File_In/collectionMachines.txt
//string[] lines = new string[] { "NameMachine" };
string[] lines = File.ReadAllLines(@"File_In/collectionMachines.txt");
foreach (var machine in lines)
{
//Retrieve the list of installed programs for each extrapolated machine name
var registry_key = @"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall";
using (Microsoft.Win32.RegistryKey key = RegistryKey.OpenRemoteBaseKey(RegistryHive.LocalMachine, machine).OpenSubKey(registry_key))
{
foreach (string subkey_name in key.GetSubKeyNames())
{
using (RegistryKey subkey = key.OpenSubKey(subkey_name))
{
//Console.WriteLine(subkey.GetValue("DisplayName"));
//Console.WriteLine(subkey.GetValue("IdentifyingNumber"));
if (subkey.GetValue("DisplayName") != null)
{
Console.WriteLine(string.Format("{0};{1};{2}", machine, subkey.GetValue("DisplayName"), subkey.GetValue("Version")));
sbOutFile.AppendLine(string.Format("{0};{1};{2}", machine, subkey.GetValue("DisplayName"), subkey.GetValue("Version")));
}
}
}
}
}
//CSV file creation
var fileOutName = string.Format(@"File_Out\{0}_{1}.csv", "Software_Inventory", DateTime.Now.ToString("yyyy_MM_dd_HH_mmssfff"));
using (var file = new System.IO.StreamWriter(fileOutName))
{
file.WriteLine(sbOutFile.ToString());
}
//Press enter to continue
Console.WriteLine("Press enter to continue !");
Console.ReadLine();
}
}
}
source to share