This is probably a version issue, but I simply need to get the server name into the Format-Table PowerShell command.
$compArray = Get-Content C:\Users\Me\Documents\ServerList_All.txt
$Proc = foreach ($strComputer in $compArray) {
Get-WMIObject Win32_Service | Where-Object {
$_.Name -like 'SQL*' -or
$_.Name -like 'MSSQL*' -or
$_.Name -like 'OLAP*' -or
$_.Name -like 'MSDTS*' -or
$_.Name -like 'MSOLAP*' -or
$_.Name -like 'ReportServer*'
} | Sort-Object -Property Name | Format-Table $strComputer, Name, State
}
$Proc | Out-File C:\Users\ME\Documents\ServerStatus_All.txt
This works in PS v2:
| Sort-Object -Property Name | Format-Table Name, State
This does not, but does work in PS v3:
| Sort-Object -Property Name | Format-Table $strComputer, Name, State
Error:
Format-Table : Cannot convert System.Management.Automation.PSObject to one of the following types {System.String, System.Management.Automation.ScriptBlock}.
The only difference is the $strComputer variable. I am reading from a text file, and everything is beautiful in v3+.
No, I cannot upgrade to a newer PS version on the server I am running this from, sadly.
This should work for you in both...
$compArray = (Get-ADComputer -Filter *).Name
$Proc = foreach ($strComputer in $compArray) {
Get-WMIObject -Class Win32_Service -ComputerName $strComputer |
Where-Object {
$_.Name -like 'SQL*' -or
$_.Name -like 'MSSQL*' -or
$_.Name -like 'OLAP*' -or
$_.Name -like 'MSDTS*' -or
$_.Name -like 'MSOLAP*' -or
$_.Name -like 'ReportServer*'
} |
Select-Object -Property #{Name = 'Computer';Expression={$strComputer}}, Name, State |
Sort-Object -Property Name |
Format-Table -AutoSize
}
$Proc
# Results
Computer Name State
-------- ---- -----
LABSQL01 MSSQLFDLauncher Running
LABSQL01 MSSQLSERVER Running
LABSQL01 SQLBrowser Stopped
LABSQL01 SQLSERVERAGENT Running
LABSQL01 SQLTELEMETRY Running
LABSQL01 SQLWriter Running
Computer Name State
-------- ---- -----
LABWSM01 MSSQL$MICROSOFT##WID Stopped
Related
I have a folder containing text-files with a standardized naming-scheme like:
2021-03-16_21-25-55_Client1_Edward.Hall_ServerResponse.json
2021-03-16_21-25-33_Client2_Eloise.Glover_ServerResponse.json
2021-03-16_21-17-38_Client3_Millie.Walsh_ServerResponse.json
2021-03-16_21-17-30_Client4_Lilly.Morton_ServerResponse.json
2021-03-16_21-15-45_Client5_Tia.Curtis_ServerResponse.json
2021-03-16_21-15-23_Client1_Edward.Hall_ServerResponse.json
2021-03-16_21-15-10_Client1_Lilly.Morton_ServerResponse.json
2021-03-16_21-15-03_Client2_Eloise.Glover_ServerResponse.json
2021-03-16_21-12-14_Client2_Eloise.Glover_ServerResponse.json
2021-03-16_21-11-25_Client3_Administrator_ServerResponse.json
I want to filter the files and retrieve the latest file (LastWriteTime) of a specific Computername-/Username-combination. Therefore I want to use a code like this:
# $env:COMPUTERNAME = "Client1"
# $env:USERNAME = "Edward.Hall"
$MyFolder = "C:\MyFolder"
Get-ChildItem -Path $MyFolder -File -ErrorAction SilentlyContinue | Where-Object {
$_.Extension -eq ".json" -and $_.COMPUTERNAME -eq $env:COMPUTERNAME -and $_.USERNAME -eq $env:USERNAME
} | Sort-Object -Descending -Property LastWriteTime | Select-Object -First 1
Of course the part -and $_.COMPUTERNAME -eq $env:COMPUTERNAME -and $_.USERNAME -eq $env:USERNAME is NOT working and should only show up the direction to what I imagine.
In the example above the result should be the file "2021-03-16_21-25-55_Client1_Edward.Hall_ServerResponse.json".
I was thinking of using -match, but it should be a exact match -eq.
Could you please help me to find a solution for this?
Thank you very much!
As long as you can count on the name format always conforming to that standard you can just split up the name strings for your required sections:
# $env:COMPUTERNAME = "Client1"
# $env:USERNAME = "Edward.Hall"
$MyFolder = "C:\MyFolder"
Get-ChildItem -Path $MyFolder -File -ErrorAction SilentlyContinue | Where-Object {
($_.Extension -eq ".json") -and ($_.Name.Split('_')[2] -eq $env:COMPUTERNAME) -and ($_.Name.Split('_')[3] -match $env:USERNAME)
} | Sort-Object -Descending -Property LastWriteTime | Select-Object -First 1
Get-WmiObject -Class Win32_Printer | where{$_.Network -eq ‘true‘}| foreach{$_.delete()}
I know this script will delete all network printers, but I need to delete only certain network printers…like CLEPRINT15-2 and CLEPRINT 15-4, but not 15-3. How would I do this?
You already have a where filter on the Network property just more conditionals on the Name property.
Get-WmiObject -Class Win32_Printer |
Where-Object {$_.Network -eq $true -and ($_.Name -eq 'CLEPRINT15-2' -or $_.Name -eq 'CLEPRINT15-4')} |
ForEach-Object {$_.Delete()}
Note: Also be careful with smart quotes. ‘ is different than '
Try this additional where condition with a RegEx class [24]:
Get-WmiObject -Class Win32_Printer |
where{$_.Network -eq $true -and $_.Name -match '^CLEPRINT-?15-[24]$'} |
foreach{$_.delete()}
I am new to PowerShell and ran into a bit of a roadblock. I am trying to pull program name and version information from multiple servers.
I have a list of the program names in a $list variable, but the program names also contain the version numbers in them. I am just storing the names of the programs in the list variable without the version numbers.
I am trying to figure out a way to use both the -like and -in parameters with the Where-Object cmdlet in order to match the full program entry name (e.g. AdToUserCacheSync 1.10.1.10) with my entry in the $list variable (e.g. AdToUserCacheSync).
How can I do this?
$list = Get-Content "\\server\c$\temp\list.txt"
$storeTestServers = Get-Content "\\server\c$\temp\testStores.txt"
foreach ($server in $storeTestServers) {
Get-WmiObject -Class Win32_Product -ComputerName $server |
Select-Object -Property PSComputerName, Name, Version |
Where-Object {$_.pscomputername -like "940*" -and $_.name -like -in "*$list*"}
}
The Where-Object FilterScript block is just a scriptblock that returns $true, $false or nothing - you can do all kinds of crazy things inside it, including looping over an array to see if there is a wildcard match in one of the entries:
Where-Object {
$ProductName = $_.Name
$_.pscomputername -like "940*" -and (
$list | ForEach-Object {
if($ProductName -like "*$_*"){ return $true }
}
)
}
I found the Adobe version by PowerShell:
Get-WmiObject -Class Win32_Product -ComputerName 127.0.0.1 |
Select-Object -Property PSComputerName, Name, Version |
Where-Object {$_.Name -like "Adobe*"} | Out-File Adobe_Log.log
I want to get the Display Name, Name, Start Mode, Start Name, and State of all Automatic services that are in a Stopped state on a Windows server. Normally, I would just do
get-wmiobject -class win32_service | ? {$_.StartMode -eq "Auto" -and $_.State -eq "Stopped"} | select DisplayName, Name, StartMode, StartName, State
However, the cmdlet above does not distinguish between a state of "Automatic" and "Automatic Delayed Start". The cmdlet I have below will not report any services that have a state of auto delayed start, but I don't know how to get it to also display the other properties I need.
(Get-WmiObject -Class Win32_Service -Filter "state = 'stopped' and startmode = 'auto'" | Select-Object -ExpandProperty name) | Where-Object {(Get-ChildItem HKLM:\SYSTEM\CurrentControlSet\Services | Where-Object {$_.property -contains "DelayedAutoStart"} | Select-Object -ExpandProperty PSChildName) -notcontains $_} | Select-Object #{l='Service Name';e={$_}}
How can I modify the above cmdlet so that it will also display the other properties I want?
EDIT:
I know the method below will work, but its inefficient and non-powershell-like.
$auto_services = #((get-wmiobject -class win32_service -filter "state='stopped' and startmode='auto'" | select-object -expandproperty name) | ? {(get-childitem HKLM:\SYSTEM\CurrentControlSet\Services | ? {$_.property -contains "DelayedAutoStart"} | Select-Object -ExpandProperty PSChildName) -notcontains $_})
foreach ($service in $auto_services) { Get-WMIobject -class win32_service | ? {$_.Name -eq $service} | Select DisplayName, name, startmode, startname, state}
EDIT 2:
What would be even better is if you could list all services and the desired properties and somehow make it so that the "Automatic Delayed Start" services actually show "Auto Delayed Start" as the StartMode instead of showing just "Auto".
Using PowerShell 4.0 (with -PipelineVariable) you can do the following :
get-wmiobject -class win32_service -PipelineVariable s | ? {$_.StartMode -eq "Auto" -and $_.State -eq "Stopped"}| where {(Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\services\$($_.name)" -Name 'DelayedAutoStart' -ErrorAction "silentlycontinue").DelayedAutoStart -eq 1} | % {select -InputObject $s -Property DisplayName, Name, StartMode, StartName, State}
Using previous versions you should assign the service object to a var during the pipeline.
get-wmiobject -class win32_service | % {$s=$_;$s} | ? {$_.StartMode -eq "Auto" -and $_.State -eq "Stopped"}| where {(Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\services\$($_.name)" -Name 'DelayedAutoStart' -ErrorAction "silentlycontinue").DelayedAutoStart -eq 1} | % {select -InputObject $s -Property DisplayName, Name, StartMode, StartName, State}
Edited
Here is a version for PowerShell 2.0 of all stopped services that are in "Automatic" startmode and not not "Automatic Delayed Start" :
get-wmiobject -class win32_service | % {$s=$_;$s} | ? {$_.StartMode -eq "Auto" -and $_.State -eq "Stopped"}| % {$d = (Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\services\$($_.name)" -Name 'DelayedAutoStart' -ErrorAction "silentlycontinue").DelayedAutoStart;$_ } | where {$d -ne '1'} |% {select -InputObject $s -Property #{name="DelayedAutoStart";expression={$d}},DisplayName, Name, StartMode, StartName, State}
How can I get the InstallDate from Win32Reg_AddRemovePrograms to display by day/month/year?
This is the command I need to use
get-wmiobject -Class Win32Reg_AddRemovePrograms -ComputerName
AComputer| where {$_.DisplayName -notlike "hotfix" -and
$_.DisplayName -notlike "Security Update" -and $_.DisplayName
-notlike "*Update for Windows *"} | select DisplayName,Version,Publisher,InstallDate
If the InstallDate looks like the InstallDate of the Win32_Product class (e.g 20131209):
[DateTime]::ParseExact('20131209','yyyyMMdd',$null).ToString('dd/MM/yyyy')
just to let you know the Win32Reg_AddRemovePrograms class is not a common class, it is added by the SMS/SCCM. It also only shows info related to 32-bit programs. Source For that reason I do not have the class available on the station and cannot provide you with the exact steps . Please provide output of this commands:
$item = $gwmi Win32Reg_AddRemovePrograms | select -first 1
$item.InstallDate
$item.InstallDate.GetType().fullname
One way is to format the date like the example below.
$date=Get-Date
Monday, December 9, 2013 5:29:50 AM
$date.ToString("dd/MM/yyyy")
09/12/2013
EDIT:
I don't have access to Win32Reg_AddRemovePrograms, so not tested.
try adding this to the end:
| %{ $_.InstallDate = ($_.InstallDate.tostring("dd/MM/yyyy") ); $_ }
So the final: (added ` for line breaks)
get-wmiobject -Class Win32Reg_AddRemovePrograms -ComputerName AComputer| `
where {$_.DisplayName -notlike "hotfix" -and $_.DisplayName -notlike "Security Update" -and $_.DisplayName -notlike "*Update for Windows *"} | `
select DisplayName,Version,Publisher,InstallDate | `
%{ $_.InstallDate = ($_.InstallDate.tostring("dd/MM/yyyy") ); $_ }
Or if it is in the date format like Shay mentioned,
| %{ $_.InstallDate = ([DateTime]::ParseExact($_.InstallDate,'yyyyMMdd',$null).ToString('dd/MM/yyyy')) ;$_}
Full script:
get-wmiobject -Class Win32Reg_AddRemovePrograms -ComputerName AComputer| `
where {$_.DisplayName -notlike "hotfix" -and $_.DisplayName -notlike "Security Update" -and $_.DisplayName -notlike "*Update for Windows *"} | `
select DisplayName,Version,Publisher,InstallDate | `
%{ $_.InstallDate = ([DateTime]::ParseExact($_.InstallDate,'yyyyMMdd',$null).ToString('dd/MM/yyyy')) ;$_}