I am writing a script to query what edition of Windows machines are on. So far I have the following code:
$ASSETNUM = Read-Host "Please enter a valid asset tag"
Get-WmiObject Win32_OperatingSystem -ComputerName $ASSETNUM | select PSComputerName, Caption, OSArchitecture, Version, BuildNumber | FL
if (Caption = "Microsoft Windows 10 Enterprise"){
Write-Host "This works"
} else {
Write-Host "This did not work"
}
The first part before the if statement works as intended. However, I wish to query the "Caption" to be able to run a further function afterwards. However, I'm at a loss on how to query this. The Write-Host parts are just for testing until I get this working.
Remove | FL because that is only to display stuff onto the screen.
Instead, capture the output in a variable and use that
$os = Get-WmiObject Win32_OperatingSystem -ComputerName $ASSETNUM | Select-Object PSComputerName, Caption, OSArchitecture, Version, BuildNumber
Next, use the $os variable to get the property you need, in this case you want
if ($os.Caption -eq "Microsoft Windows 10 Enterprise"){
Write-Host "This works"
}
else {
Write-Host "This did not work"
}
P.S. The = is an assignment, in case you want to compare something inside an if(), you need to use PowerShell's comparison operator -eq
Related
Im collecting information about WMI query. I save this information in a variable. When i write this variable in console, it shows me the following :
#{PasswordState=7}
But, when i do an "If" and check if variable contains the number 7, it tell me that is not contained:
If($PasswordState -contains "7")
{
Write-Host Contain 7
}
Else
{
Write-Host Not contain 7
}
Could anyone help me to get the value of WMI Query as INT? I mean, i only need the number status of PasswordState in class Lenovo_BiosPasswordSettings.
It seems the WMI is returning an object and my variable is not processing well this returning.
Thank you
$PasswordState = Get-WmiObject -Class Lenovo_BiosPasswordSettings -namespace root\wmi | Select PasswordState
Write-Host $PasswordState
If($PasswordState -contains "7")
{
Write-Host Contain 7
}
Else
{
Write-Host Not contain 7
}
I expect the output #{PasswordState=7} to be only 7.
Your output is formatted in a hashed key=value pair, and you want just the value. You can use the -ExpandProperty parameter to assign the value to $PasswordState...
$PasswordState = Get-WmiObject -Class Lenovo_BiosPasswordSettings -namespace root\wmi | Select-Object -ExpandProperty PasswordState
If ($PasswordState -contains "7") {
Write-Host "Contain 7"
}
Else {
Write-Host "Not contain 7"
}
You should definitely research and use the evaluation operator that best suits your scenario. -Contains may not be it.
I'm trying to downgrade TPM on several HP laptops. I'm attempting to create a powershell script that will grab the TPM Manufacturer Version number, and check that number against a list of possible numbers. Once it matches one of those number execute the program to downgrade the TPM version.
I started with throwing the output into a variable, and attempting to check the variable against a static number to start the correct program. The variable is stored, but when I try to check it against "7.61" it doesn't seem to be actually checking the result. The result of 7.61 is not returning "Success"
I realize powershell is different, and my IF ELSE statements are probably just outdated. Any help would be very appreciated!
Assume TPM ManufacturerVersion is 7.61
$variable = get-WmiObject -Namespace root\cimv2\security\microsofttpm -Class Win32_Tpm | Select-Object ManufacturerVersion | Out-String
if($variable -eq "8"){
Write-Host "success"
}else{
Write-Host "Fail"
}
enter image description here
You are comparing strings, rather than 'versions'. If you are only checking for simple equality, then using a direct string comparison will do:
PS C:\> "10.5" -eq "10.5"
True
However, if you want to determine, say, if one version is greater than another, strings won't work. For example:
PS C:\> "100.5" -gt "55.3"
False
In that case, you should cast the version strings to actual Version types, then the comparison will work properly. For example:
$tmp = Get-WmiObject -Namespace "root\cimv2\security\microsofttpm" -Class Win32_TPM
if ([Version]$tmp.ManufacturerVersion -eq [Version]"8.0")
{
"Success"
}
else
{
"Fail"
}
Also, if you need to compare the TPM version against multiple possibilities, then a switch statement makes for neater code:
$tmp = Get-WmiObject -Namespace root\cimv2\security\microsofttpm -Class Win32_TPM
Set-Location "C:\Users\ADministrator\Desktop\TPM Downgrade"
switch([Version]$tmp.ManufacturerVersion)
{
{$_ -eq [Version]"7.62"} { '.\7.62 downgrade.cmd'}
{$_ -eq [Version]"7.61"} { '.\7.61 downgrade.cmd'}
{$_ -eq [Version]"7.60"} { '.\7.60 downgrade.cmd'}
{$_ -eq [Version]"7.41"} { '.\7.41 downgrade.cmd'}
{$_ -eq [Version]"7.40"} { '.\7.40 downgrade.cmd'}
default {"Unable to find downgrade BIN for your firmware version"}
}
Try this one
$variable = get-WmiObject -Namespace root\cimv2\security\microsofttpm -Class Win32_Tpm | Select-Object ManufacturerVersion
if($variable.ManufacturerVersion -eq "8"){
Write-Host "success"
}else{
Write-Host "Fail"
}
Thank you all for your feedback and help. This is the final product and its working great.
$tmp = get-WmiObject -Namespace root\cimv2\security\microsofttpm -Class Win32_TPM
Set-Location "C:\Users\ADministrator\Desktop\TPM Downgrade"
if ([Version]$tmp.ManufacturerVersion -eq [Version]"7.62"){
& '.\7.62 downgrade.cmd'
}elseif ([Version]$tmp.ManufacturerVersion -eq [Version]"7.61"){
& '.\7.61 downgrade.cmd'
}elseif ([Version]$tmp.ManufacturerVersion -eq [Version]"7.60"){
& '.\7.60 downgrade.cmd'
}elseif ([Version]$tmp.ManufacturerVersion -eq [Version]"7.41"){
& '.\7.41 downgrade.cmd'
}elseif ([Version]$tmp.ManufacturerVersion -eq [Version]"7.40"){
& '.\7.40 downgrade.cmd'
}else{
Write-Host "Unable to find downgrade BIN for your firmware version"
}
I'm creating a script that finds and displays IP configuration information. I have managed to create the variables to get the information and to display it:
$ip = (Get-WmiObject -Class win32_networkadapterconfiguration -Filter "index = '12'").IPAddress[0]
$subnet = (Get-WmiObject -Class win32_networkadapterconfiguration -Filter "index = '12'").IPSubnet[0]
$gateway = (Get-WmiObject -Class win32_networkadapterconfiguration -Filter "index = '12'").DefaultIPGateway
$dns = (Get-WmiObject -Class win32_networkadapterconfiguration -Filter "index = '12'").DNSServerSearchOrder
write-host
write-host
write-host "IP address is: $ip"
write-host "Subnet Mask is: $subnet"
write-host "Default Gateway is: $gateway"
write-host "DNS is: $dns"
I'm filtering the interface by index number, which for my case the number is 12 for the right interface. I want to prompt the user with a list of network interfaces. Get-NetAdapter command should not be used because it doesn't work on PowerShell v2. The user must be able to see current interfaces including descriptions and be able to select one netowrk adapter interface. The selected interface must be put into a variable i.e. $interface. The variable must output the corresponding adapter index number. After that, I am able to place the variable in the filter command like: -Filter "index = '$interfaceindexnumber'" which should normally display IP information for the selected interface.
Feel free to use a different filter if you believe index number is not the right solution for this case. Please, make sure to use commands that work with PowerShell v2.
Thank You!
Based on the description of what you are trying to do, which is to allow a user to select an interface that is later used to provide information to you or your script, I took your script and scrubbed it a little bit as well as added in Out-GridView which is great for presenting information to a user. All of these commands should work in PowerShell v2.
I started out by doing just one WMI query and storing it in a variable. Then I pass filtered information to the Out-GridView cmdlet for the user to select whichever interface they want or need to select. I chose to only show the user Description, IPAddress, and Index to prevent too much confusion.
After the user makes the selection, it is assigned to $interface. To extract the full information that was originally queried from win32_networkadapterconfiguration I used the index number of the users selection to filter against $AllNetInterfaces. This could be simplified by just passing all of the information to the Out-GridView to begin with, but again since you plan on having users make selections and such, less is more.
Finally, I call the properties of the object without using the "Write-Host" function because at this point I am validating that it worked and I am not really sure what you are going to do with it later on.
$AllNetInterfaces = Get-WmiObject -Class win32_networkadapterconfiguration -Property *
$Interface = $AllNetInterfaces | Select Description, IPAddress, Index | Out-GridView -Title "Available Network Adapters" -OutputMode Single
$Interface = $AllNetInterfaces | ? {$_.Index -match $Interface.Index}
$Interface.IPAddress[0]
$Interface.IPSubnet[0]
$Interface.DefaultIPGateway
$Interface.DNSServerSearchOrder
If what you are trying to do is show the user the IP information without using ipconfig, then you could use the Out-GridView cmdlet once again, like this:
$Interface | Select IPAddress, IPSubnet, DefaultIPGateway, DNSServerSearchOrder | Out-GridView -Title "IP Info for: $($Interface.Description)"
Get-WmiObject -Class win32_networkadapterconfiguration | Select Index, #{n="IP"; e={$_.ipaddress[0]}}, #{n="Subnet"; e={$_.IPSubnet[0]}}, Description | Format-Table -AutoSize
[int]$ifindex = Read-Host "Select Network Adapter by Index Number"
$adapters = Get-WmiObject -Class win32_networkadapterconfiguration -Filter "index = '$ifindex'"
foreach ($adapter in $adapters){
$ip = $adapter.IPAddress[0]
$subnet = $adapter.IPSubnet[0]
$gateway = $adapter.DefaultIPGateway
$dns = $adapter.DNSServerSearchOrder
}
$ip
$subnet
$gateway
$dns
I am querying remote servers for their operating system. I know that I can return the Version, but I want to replace these values with the friendly name. The code I have so far is:
$Computer = (gc c:\servers.txt)
$BuildVersion = Get-WmiObject -Class Win32_OperatingSystem -Property Version, CSName -ComputerName $Computer -ErrorAction SilentlyContinue
$Build=$BuildVersion.version
If ({$BuildVersion.Version -match "5.2.3790"})
{$Build="2003"}
Elseif ({$BuildVersion.Version -match "6.1.7601"})
{$Build="2008"}
Elseif ({$BuildVersion.Version -like "6.3.9600"})
{$Build="2012"}
But this doesn't seem to work and only returns "2003" regardless. Please help, I'm fairly new to PS and coding.
thanks
The problem is your if statements. Putting the Boolean expression inside squiggly brackets makes it a script block, and that's going to get cast as a string before being cast as a Boolean. Strings cast to Booleans always evaluate to true unless they're empty.
PS C:\> {$BuildVersion.Version -match "5.2.3790"}
$BuildVersion.Version -match "5.2.3790"
PS C:\> ({$BuildVersion.Version -match "5.2.3790"}) -as [bool]
True
PS C:\> $BuildVersion.Version -match "5.2.3790"
False
PS C:\> ($BuildVersion.Version -match "5.2.3790") -as [bool]
False
So what you're running is essentially:
if ([bool]'$BuildVersion.Version -match "5.2.3790"') [...]
And that's always going to be true.
Try:
$Computer = (gc c:\servers.txt)
$BuildVersion = Get-WmiObject -Class Win32_OperatingSystem -Property Version, CSName -ComputerName $Computer -ErrorAction SilentlyContinue
$Build=$BuildVersion.version
If ($BuildVersion.Version -match "5.2.3790")
{
$Build = "2003"
}
Elseif ($BuildVersion.Version -match "6.1.7601")
{
$Build = "2008"
}
Elseif ($BuildVersion.Version -like "6.3.9600")
{
$Build = "2012"
}
Bottom line is that squiggly brackets are not parentheses and you can't use them like they are.
However, there's also a major logic error here. You're potentially fetching an array for $BuildVersion because you're reading from a file, but then you treat it like a single value. You never loop through $BuildVersion. However, I do not have enough information about what you're actually trying to do with your script (like what you do with $Build) to be able to fix that.
I originally said this, but I've since changed my mind
The reason this is only returning 2003 is that you're only running your If code on a single entry in the list.
Wrong
As TessellatingHeckler says, the reason your if wasn't working is that you had too many curly braces, so PowerShell wasn't actually evaluating your logic.
However, you still need to step through each of the computers to do what you're trying to do. We'll do that by adding in a ForEach loop. I also went ahead and replaced your If {} logic with a Switch statement, which I think is easier to understand for a scenario like this with multiple clauses. If's just get way too verbose.
Finally, I'm assuming you want to output the results too, so I added a custom object here, which is just a way of choosing which properties we want to display.
$Computer = (gc c:\servers.txt)
ForEach ($system in $computer){
$BuildVersion = Get-WmiObject -Class Win32_OperatingSystem -Property Version, CSName -ComputerName $system -ErrorAction SilentlyContinue
$Build=$BuildVersion.version
switch ($build){
"5.2.3790" {$Build="2003"}
"6.1.7601" {$Build="2008"}
"6.3.9600" {$Build="2012"}
}
#output results
[pscustomobject]#{Server=$system;OSVersion=$build;CSName=$buildVersion.CSname}
}#EndOfForEach
Output
>Server OSVersion CSName
------ --------- ------
dc2012 2012 DC2012
sccm1511 2012 SCCM1511
You can use this:
Get-WmiObject -Class Win32_OperatingSystem | Select-Object -ExpandProperty Caption
Additionally you can see everything this WMI object holds like this:
Get-WmiObject -Class Win32_OperatingSystem | fl *
Edit: if you want to remove some text from the string, you can use -replace:
(Get-WmiObject -Class Win32_OperatingSystem |
Select-Object -ExpandProperty Caption) -replace "Microsoft Windows Server ",""
So I've successfully been able to retrieve a list of all the installed programs on my computer and have been able to store them into an array with the following code:
Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate |
Format-Table –AutoSize
Now what I am trying to do is output a list of the only the names of the programs, which I have already done, but allow the user to type in the name of the program they'd like to view more information about and have some command go through, find the program, and output the properties for ONLY that program. Any tips?
You are not really specific what you are looking for but this would satisfy what little you provided. Display the names to the user. Continue prompting until they do not enter anything. For every match we display the pertinent results to the user and continue the prompt.
# Gather information
$productDetails = Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate
# Display teaser information to the user
$productDetails | Select-Object DisplayName
do {
Write-Host "--McPrompter 5000--" -ForegroundColor Green
$response = Read-Host "Type a partial software title or <Enter> to quit"
# If there is text lets see if there is a match
If($response){
$results = $productDetails | Where-Object{$_.DisplayName -like "*$response*"}
If($results){
$results | Format-Table -AutoSize
} Else {
Write-Host "No match for $response. Please try again." -ForegroundColor Red
}
}
} until (!$response)
Note about that key
Understand that you will need to check the syswow64 key if the system is x64 to get the complete list. You should be able to find more information about that here or on the Google.
You can basically try simple things, by displaying the list of Softwares and have your logic after the selection.
$Softwares = Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName, DisplayVersion, Publisher, InstallDate
$Choice = #{}
$Number = 1
foreach ($Software in $Softwares.DisplayName)
{
$Choice.add($Number,$Software)
$Number = $Number + 1
}
$Choice | Format-Table
[Int]$MenuChoice = read-host "Please enter your choice"
Switch($MenuChoice)
{
1{
Write-Host "Selected Software is" $Choice.get_item($MenuChoice);
#Your Logic here
}
2{
#Your Logic here
}
default{"please select a valid Software"}
}
Hope this helps!!