Hey all,

Long story short, we’re encrypting desktops, and they must be on UEFI. Sadly, most of the machines here are still on BIOs. I found a script to check if a machine is in legacy or UEFI, but I don’t know how to make it check our machines. I’m thinking I could export a list of all of our computer names, and have it loop through that if that’s best? Then maybe make a new report in a new file stored somewhere? Can anyone help me get it into a looping/checking mode?

 $d = Confirm-SecureBootUEFI -ErrorVariable ProcessError
if ($ProcessError)
{
$wshell = New-Object -ComObject Wscript.Shell
$wshell.Popup("legacy",0,"BOOTMODE",0x1)
}
else
{
$wshell = New-Object -ComObject Wscript.Shell
$wshell.Popup("UEFI",0,"BOOTMODE",0x1) 
}

5 Spice ups

Are those machines in AD, or do you have a list?

You could try something like this?

$comp = Import-Csv "computerlist.csv"
Invoke-Command -ComputerName $comp -ScriptBlock {
$d = Confirm-SecureBootUEFI -ErrorVariable ProcessError
if ($ProcessError)
{
$wshell = New-Object -ComObject Wscript.Shell
$wshell.Popup("legacy",0,"BOOTMODE",0x1)
}
else
{
$wshell = New-Object -ComObject Wscript.Shell
$wshell.Popup("UEFI",0,"BOOTMODE",0x1) 
}        
}

They are all in AD, but in several OUs if that matters.

That would import them, but then I just get a pop up for each machine? I wouldn’t know which machine it’s testing though unless I count them and record it myself? I don’t know if this script is ideal, it’s the only one I found, and is designed for just one machine.

how about like so:

$computers = (get-adcomputer -filter *).name

$Info = foreach ($machine in $computers) {
            if (test-connection $machine -Count 1 -Quiet) {
                invoke-command -ComputerName $machine -ScriptBlock {
                    try {
                        Confirm-SecureBootUEFI -ErrorAction Stop
                        Write-Output "'$env:computername' has UEFI"
                    }
                    catch {
                        Write-Output "'$env:computername' has BIOS"
                    }
                }
            }
            else{
                Write-Output "'$machine' is not reachable."
            }
        }
$info | out-file "$env:userprofile\desktop\result.txt"

Of course, if you don’t want all AD computers, you have to adjust the filter.

1 Spice up

That looks great. What would filters look like for 2 groups and a subgroup? Computers, Surface, and inside Computers is “Advisors & Assistants”

And that set is the same but for 4 cities, I can mod the script for each of the four runs if necessary.Capture.PNG

So your issue appears to be 2 fold.

  1. you need to get a list of the computers in your AD. Here’s how I recently did that in my AD:
$Company = "ou=XXXX,dc=Company,dc=Local"

Write-host Please enter the region you would like to query

$Region = Read-Host

Write-host Please enter the Site you would like to query

$Site = Read-Host

$Searchb = "ou=Computers,ou="+"$Site"+",ou="+"$Region"+","+"$Company"

$workstations = (Get-ADComputer -SearchBase "$Searchb" -filter * -Properties Name  | select-object -ExpandProperty Name )

$Workstations | Out-File p:\"$Site"_MachineNames.txt -Append -noclobber

You likely will have to adjust this for your companies AD structure, but this should give you something of a template. Adjust the first line to conform with your company AD structure, as well as possibly the “$SearchB =” variable value. Adjust the last line to output the file wherever you want it to be. You should now have a list of computer names for that site. I have to run but if you are still having issues with what I assume will be a foreach loop that will use the list of computers as the input I will check back when I have a minute.

Have you done some research or tried anything to get a filter adjusted with powershell… ?

$ous = 'OU=Test 1,DC=domain,DC=com', 'OU=Test 2,DC=domain,DC=com'
$info = foreach ($ou in $ous) {
    foreach ($machine in (get-adcomputer -filter * -searchbase $ou)) {
        if (test-connection $machine -Count 1 -Quiet) {
            invoke-command -ComputerName $machine -ScriptBlock {
                try {
                    Confirm-SecureBootUEFI -ErrorAction Stop
                    Write-Output "'$env:computername' has UEFI"
                }
                catch {
                    Write-Output "'$env:computername' has BIOS"
                }
            }
        }
        else {
            Write-Output "'$machine' is not reachable."
        }
    }
}
$info | out-file "$env:userprofile\desktop\result.txt"

Yes, like this one: AD PowerShell - Replace nested groups with members of said group

But trying to follow that code, and then apply it to what you have doesn’t make sense to me. Attempting to tease out the sub-sub-sub group in AD, without screwing up the rest of the code is the part I struggle with in Powershell.

You just list them individually

$ous = 'OU=Computers,DC=domain,DC=com', 'OU=Surface,DC=domain,DC=com',
       'OU=Advisors & Assistants,OU=Computers,DC=domain,DC=com'
$info = foreach ($ou in $ous) {
    foreach ($machine in (get-adcomputer -filter * -searchbase $ou)) {
        if (test-connection $machine -Count 1 -Quiet) {
            invoke-command -ComputerName $machine -ScriptBlock {
                try {
                    Confirm-SecureBootUEFI -ErrorAction Stop
                    Write-Output "'$env:computername' has UEFI"
                }
                catch {
                    Write-Output "'$env:computername' has BIOS"
                }
            }
        }
        else {
            Write-Output "'$machine' is not reachable."
        }
    }
}
$info | out-file "$env:userprofile\desktop\result.txt"

You can also choose registry


```
$ErrorActionPreference="silentlycontinue"
$Computers='OU=Computers,DC=domain,DC=com', 'OU=Surface,DC=domain,DC=com','OU=Advisors & Assistants,OU=Computers,DC=domain,DC=com' |%{Get-ADComputer -Filter '*' -SearchBase $_} | Select -ExpandProperty Name
Foreach ($Computer in $Computers) 
{if(!(Test-Connection -Cn $computer -BufferSize 16 -Count 1 -ea 0 -quiet))
{write-host "cannot reach $computer" -f red}
Else{
$RegBase = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey([Microsoft.Win32.RegistryHive]::LocalMachine,$Computer)
$Reg=$RegBase.OpenSubKey(‘System\CurrentControlSet\control\SecureBoot\State’)

if (!$reg) 
{
Write-Host "Secure Not Boot enabled on $Computer"
}

else 
{
Write-Host "Secure enabled on $Computer" -f green
}

}
}
```

I’m getting an error, and thought maybe I had to import the Active Directory module, so I added that, but that didn’t fix it. I do also have RSAT on this machine.

get-adcomputer : Directory object not found
At C:\Users\beesoj\Desktop\BiosTest.ps1:5 char:27
+ ...    foreach ($machine in (get-adcomputer -filter * -searchbase $ou)) {
+                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (:) [Get-ADComputer], ADIdentityNotFoundException
    + FullyQualifiedErrorId : ActiveDirectoryCmdlet:Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException,Microsoft.ActiveDirectory.Management.Comm 
   ands.GetADComputer

Line 5, char 27 is the "a’ in adcomputer. I added the “import-module activedirectory” to the beginning of the code, but no change.

I also found this article, and after trying those suggestions, I still get the same error. Sysadmin Still Surviving: Powershell is Being a Pain ("Get-ADUser is not recognized...")

I’m on Windows 10, v1709 with that version of RSAT if that makes a difference.

Nope, that means it can not find your OU path.

OU=Advisors & Assistants,OU=Computers,DC=domain,DC=com

^ you adjusted those to your actual domain information, yes?

If you run this:

# insert the actual computername
get-adcomputer $computername

the DistinguishedName will show you the OU path

e.g.

CN=NTADMIN,OU=666,OU=OPS,DC=BLOODYSHELL,DC=COM

That means the Ou info would be

OU=666,OU=OPS,DC=BLOODYSHELL,DC=COM

Yes, I updated those.
$ous = ‘OU=1142_STL,OU=Computers,DC=(updated) ,DC=mds’, ‘OU=1142_STL,OU=Surface,DC=(updated),DC=mds’,

‘OU=1142_STL,OU=Computers,OU=Advisors & Assistants,DC=(updated),DC=mds’

And the get computer-name shows: DistinguishedName : CN=TABSTL05,OU=Surface,OU=1142_STL,DC=(domain),DC=mds

There’s a pic of the AD setup a few posts up to verify names.

Yep, so all your OU names are wrong, you have to write it like this ^

$ous = 'OU=Computers,OU=1142_STL,DC=(domain),DC=mds', 
       'OU=Surface,OU=1142_STL,DC=(domain),DC=mds',
       'OU=Advisors & Assistants,OU=Computers,OU=1142_STL,DC=(domain),DC=mds'

Gotcha, that worked. Sort of. I got a report, but it says all machines are “not reachable”. What kind of connection is it (not) establishing? It also couldn’t even “Reach” my own computer.

‘CN=TABSTL05,OU=Surface,OU=1142_STL,DC=(domain),DC=mds’ is not reachable.

‘CN=wsstl136,OU=Computers,OU=1142_STL,DC=(domain),DC=mds’ is not reachable.
‘CN=WSSTL173,OU=Computers,OU=1142_STL,DC=(domain),DC=mds’ is not reachable.

Well, I guess that sounds like this fails:

test-connection $machine -Count 1 -Quiet

If you insert your own computername, do you get a true?

I am very surprised to see the whole name I expected just the computername
→ ‘CN=wsstl136,OU=Computers,OU=1142_STL,DC=(domain),DC=mds’ is not reachable.
→ Rather ‘PC123’ is not reachable.

test-connection $machine

Ugh maybe that’s part of the issues, let’s select just name

#replace
foreach ($machine in (get-adcomputer -filter * -searchbase $ou)) {

#with

foreach ($machine in ((get-adcomputer -filter * -searchbase $ou).name)) {

test-connection tabstl05 -Count 1 -Quiet

That gives me a True result.

Testing my bosses, and a few others that I know are turned on brings back a True.