The name passed to IndexOf must match exactly with what's in Printer.Printers in order to work. If they're not exact, including CASE, IndexOf will return -1, which means "use the default printer".
For a specific example, using IndexOf('hp laserjet') will return -1 if the actual printer name is HP LaserJet or hp laserjet 5.
If you're not specifying the exact name, you can do a partial match by iterating the list. It's highly unlikely that the typical system has too many printers available for this to be efficient; we have a couple of dozen, and it's fine.
Here's the situation we have: Our office is divided into three basic departments (Fiscal, Admin, and Customer Service). Each has a different printer that holds pin-feed (dot matrix) labels, but we have apps that run in all departments. Instead of having the application know which department it's being run in to choose the label printer, we just give the printers names containing the word Labels - Fiscal Labels, Admin Labels, etc. We can then find the appropriate printer with a loop:
function GetLabelPrinterIndex: Integer;
var
i: Integer;
begin
for i := 0 to Printer.Printers.Count - 1 do
if AnsiContainsText(Printer.Printers[i], `Labels`) then
begin
Exit(i);
end;
Result := -1;
end;
As a note: I'd remove the VCL prefix from your references; it means your code won't be available across platforms. If you just make sure that Printers is in your uses clause, you can use just Printers.Printer, and changing the target platform (VCL Win32/64, FMX 32/64, OSX) will adjust the uses clause for you based on the build configuration.