How do I properly use $_ in out-file? Here's my code:
get-content computers.txt |
Where {$_ -AND (Test-Connection $_ -Quiet)} |
foreach { Get-Hotfix -computername $_ } |
Select CSName,Description,HotFixID,InstalledBy,InstalledOn |
convertto-csv | out-file "C:\$_.csv"
I'm trying to execute a get-hotfix for all the computers listed in the text file then I want them to be exported to CSV with the computer name as the filename.
You need one pipeline to process the computers.txt files, and a nested one inside the foreach to process the list of hotfixes for each computer:
get-content .\computers.txt |
Where {$_ -AND (Test-Connection $_ -Quiet)} |
foreach {
Get-Hotfix -computername $_ |
Select CSName,Description,HotFixID,InstalledBy,InstalledOn |
convertto-csv | out-file "C:\$_.csv"
}
Edit: Changed computers.txt to .\computers.txt, as this is required for local paths in powershell
i can see with this:
get-content .\computers.txt | Where {$_ -AND (Test-Connection $_ -Quiet)} | foreach{ Get-Hotfix -id KB4012212 -computername $_ | Select CSName,Description,HotFixID,InstalledBy,InstalledOn | convertto-csv | out-file "C:\$_.csv" }
i can see only in which PC is the fix (KB4012212) installed.
it's possible to see the following
CSNAME Fix(Inst/NotInst)
PC1 FIxInstalled
PC2 FixNotinstalled
PC3 FixnotInstalled
..
..
etc
I monkeyed with this for a while and nothing I found on-line worked until I used this combo.
I used the method is this thread but it was SO slow and I wanted to learn more about using jobs so this is what ended up working for me on Windows 7 PS Ver 4.
All other options were either too slow or did not return data from the remote system.
$VMs = get-content C:\WinVms.txt #Generate your hostnames list however you deem best.
foreach ($vm in $vms)
{
Write-Host "Attempting to get hotfixes on:" $vm
invoke-command -computername $vm -ScriptBlock {start-job -scriptblock {(get-hotfix | sort installedon)[-1]} | wait-job | receive-job} -AsJob
}
start-sleep 60 # give it a minute to complete
get-job | ? { $_.state -eq "Completed"} | receive-job -keep | export-csv c:\temp\win-patch.csv
you can check your failures too like this:
get-job | ? { $_.state -eq "Failed"}
Related
Noob here, I need to extract some data from a cim interrogation of a list of servers, however the csv output is just the same reiteration of the local server, with the sum total equaling the number of lines in the input file. I think I'm doing something wrong with the array but Ive been beating my head. Help?
$ErrorActionPreference = 'SilentlyContinue'
#Define Some Variables
$importpath = "c:\directory1"
$workingpath = "c:\directory2"
#Do Some Filtering
Import-CSV -Path "$importpath\somefile.csv" | where {$_.Powerstate -ne "PoweredOff"} | where Guest -notlike *somestring* | Export-Csv "$workingPath\PRODUCTION.csv" -NoTypeInformation
Import-csv -Path "$workingPath\PRODUCTION.csv" | Select-Object -Property Name | Export-Csv -Path "$workingpath\SERVERS.csv" -NoTypeInformation
#Create final input foreach routine
Import-CSV -Path "$workingpath\SERVERS.csv" | Out-file $workingpath\SERVERS.txt
$servers = Get-Content -path "$workingpath\SERVERS.txt"
$results = foreach ($server in $servers) {
Get-CimInstance -ClassName win32_OperatingSystem -ErrorAction SilentlyContinue | Select-Object *
}
$results | Export-Csv -Path "$workingPath\PRODUCTIONRESULTS.csv" -NoTypeInformation -Append
Try including the computername when you run the Get-CimInstance command
$results = foreach ($server in $servers) {
Get-CimInstance -ComputerName $server -ClassName win32_OperatingSystem -ErrorAction SilentlyContinue | Select-Object *
}
I'm working on an application that lists all of the installed programs on a customer's computer. I've been able to get a list based on registry keys, but it doesn't include things that were installed via the Microsoft Store. It looks like using PowerShell (based on the guidance on this page: https://mhelp.pro/how-to-uninstall-windows-apps/) I can get lists of installed applications, but what I'm getting there seems to include a lot of items that aren't in Add/Remove Programs, and I'm not sure how to reconcile the 2 sources (Add/Remove Programs and the lists of programs via PowerShell). Is there some better way I should be doing this, or is there a flag or criteria that I should be using to determine if a listed application is present in Add/Remove Programs?
Perhaps something like that did you mean ?
Refer to How to Create a List of Your Installed Programs on Windows
$outputFile = "$env:APPDATA\Installed_Applications.txt"
$OS_Architecture = $env:PROCESSOR_ARCHITECTURE
if($OS_Architecture -eq 'x86')
{
#write-host '32-bit'
$key = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*"
}
else
{
#write-host '64-bit'
$key = "HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*"
}
Get-ItemProperty $Key |
Select-Object DisplayName, DisplayVersion, Publisher, InstallDate |
Format-Table –AutoSize |
Out-File $outputFile -Encoding UTF8 -Force
Start-Process $outputFile
EDIT : 25/08/2020 # 18:20
Here is a Self-elevate script to get everything with admin rights :
cls
# Self-elevate the script if required
if (-Not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator')) {
if ([int](Get-CimInstance -Class Win32_OperatingSystem | Select-Object -ExpandProperty BuildNumber) -ge 6000) {
#$CommandLine = "-File `"" + $MyInvocation.MyCommand.Path + "`" " + $MyInvocation.UnboundArguments
$CommandLine = $MyInvocation.InvocationName
Start-Process -FilePath PowerShell.exe -Verb Runas -ArgumentList $CommandLine
Exit
}
}
$outputFile = "$env:APPDATA\Installed_Applications.txt"
$OS_Architecture = $env:PROCESSOR_ARCHITECTURE
if($OS_Architecture -eq 'x86')
{
#write-host '32-bit'
$key = "HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*"
}
else
{
#write-host '64-bit'
$key = "HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*"
}
Get-ItemProperty $Key |
Select-Object DisplayName, DisplayVersion, Publisher, InstallDate |
Format-Table –AutoSize | Out-String -Width 300 |
Out-File $outputFile -Encoding UTF8 -Force
Get-AppxPackage -AllUsers |
Out-File -Append $outputFile -Encoding UTF8 -Force
Start $outputFile
In powershell 5 but not powershell 7:
get-package
I am using the following code to export errors and warnings from all event logs into one text file.
It works but is very slow and some of the messages are truncated. I wondered if there was a more efficent way of coding it. I'm new to powershell so would appreciate your thoughts or ideas.
$Logs = Get-Winevent -ListLog *
foreach ($Log in $Logs) {
Get-WinEvent -LogName $Log.LogName -ErrorAction SilentlyContinue | ?{$_.Level -eq 1 -or $_.Level -eq 2 -or $_.Level -eq 3} | Sort-Object ProviderName, TimeCreated -descending | Out-String -Width 1000 | Format-Table -AutoSize | Tee-Object -file "c:\common\logs\Eventlog_Export.log" -Append
}
This took me about 30 seconds. You can filter by date too.
$Logs = Get-Winevent -ListLog *
foreach ($Log in $Logs) {
Get-WinEvent -filterhashtable #{logname = $Log.LogName; level=1,2,3} -ErrorAction SilentlyContinue |
select LogName,TimeCreated,Id,LevelDisplayName,Message |
export-csv -append log.csv
}
level=1,2,3 doesn't work over invoke-command for some reason.
I am trying to get all the list of KB installed on multiple servers and get the last reboot time of the system. My requirement is to get the result in csv or text format with column name "Hostname" , "KB Name" , "installed by" , "installed on" and "Last reboot". I have to execute 2 script to get this done and then i have to format it and i dont want other columns which i am receiving from code 1 only limited column are required.. Can some please help me to get the same format which i reuired?
Output required in below format :
"Source" "Description" "HotFixID" "InstalledBy" "InstalledOn" "Last Reboot"
Please find below 2 code.
FYI : I am new to powershell.
Code 1: This will list all KB installed patch.
$computers = Get-Content -path "C:\Users\joy\Desktop\Machine_List.txt"
$patches = Get-Content -path "C:\Users\joy\Desktop\KB_List.txt"
foreach ($computer in $computers){
foreach ($patch in $patches){
Get-HotFix -id $patch -ComputerName $computer | -OutVariable results -ErrorAction SilentlyContinue
if ($results -ne $null) {
$results | Out-File C:\Users\joy\Desktop\report1.txt -Append -Force
}
else {
Add-content "$Patch is not Present in $computer" -path "C:\Users\joy\Desktop\report2.txt"
}
}
Code 2: This will get the last reboot of the system.
$machines = Get-Content C:\Users\joy\Desktop\Machine_List.txt
$report = #()
$object = #()
foreach($machine in $machines)
{
$machine
$object = gwmi win32_operatingsystem -ComputerName $machine | select csname, #{LABEL='LastBootUpTime';EXPRESSION={$_.ConverttoDateTime($_.lastbootuptime)}}
$report += $object
}
$report | Export-csv C:\Users\joy\Desktop\Reboot.csv
$computers = Get-Content C:\Users\XXXXXXXX\Desktop\Machine_List.txt
$patchlist = Get-Content C:\Users\XXXXXXXX\Desktop\KB_List.txt
foreach($computer in $computers)
{
Get-HotFix -ComputerName $computer -Id $patchlist | select
InstalledOn,InstalledBy,Description,HotFixID,__SERVER | Format-Table | Out-File
C:\Users\XXXXXXXX\Desktop\report1.txt
#Get-CimInstance -ClassName Win32_Operatingsystem | select csname, lastbootuptime |
Format-Table |Out-File C:\Users\XXXXXXXX\Desktop\report1.txt
gwmi win32_operatingsystem -ComputerName $computer | select csname,
#{LABEL='LastBootUpTime';EXPRESSION={$_.ConverttoDateTime($_.lastbootuptime)}} | Out-
File C:\Users\XXXXXXXX\Desktop\report1.txt -Append
}
Try this, This will allow you to get information what you are looking for. But this script only get installed patches information from the remote machines, If you want add one more loop to print the patches which are installed on another text file.
I wanted to extract a list of users logged on to remote pc, the ps names would be fed in using a .csv file.
I was able to get a command
Get-WmiObject Win32_LoggedOnUser -ComputerName $Computer | Select Antecedent -Unique
to query the user names, could any one help me more on how to write this code?
Assuming the csv file contains a ComputerName header:
Import-Csv computers.csv | Foreach-Object{
Get-WmiObject Win32_LoggedOnUser -ComputerName $_.ComputerName | Select-Object __SERVER,Antecedent -Unique | Foreach-Object {
$domain,$user = [regex]::matches($_.Antecedent,'="([^"]+)"') | Foreach-Object {$_.Groups[1].Value}
$_ | Select-Object __SERVER,#{Name='Domain';Expression={$domain}},#{Name='User';Expression={$user}}
}
}