Preheat oven to 375°F (190°C). Grease a 9x13 inch baking dish with butter or cooking spray.
Peel potatoes and slice into 1/8 inch (3 mm) rounds using a mandoline slicer. Place slices in cold water to prevent browning, then drain and pat thoroughly dry.
Dice ham into 1/2 inch (1.2 cm) pieces. If using onion, slice into thin half-moons.
Melt butter in a medium saucepan over medium heat. Whisk in flour and cook for 1-2 minutes until golden and nutty. Slowly pour in warmed milk, whisking constantly, then add heavy cream.
Cook sauce, stirring frequently, until thickened enough to coat the back of a spoon, about 5-7 minutes. Remove from heat and stir in 1 cup cheddar and all gruyere until melted and smooth.
Season sauce with salt, pepper, garlic powder, onion powder, and smoked paprika. Taste and adjust seasoning as needed.
Spread a thin layer of sauce in the baking dish. Layer one-third of potatoes, half the ham and onion (if using), and one-third of sauce. Repeat layers, then finish with remaining potatoes and sauce. Sprinkle remaining cheddar on top.
Cover tightly with foil and bake for 45 minutes. Potatoes should be mostly tender when pierced with a knife.
Remove foil and bake uncovered for 20-25 minutes until golden and bubbly. For extra browning, broil for 2-3 minutes, watching closely.
Let the casserole rest for 10-15 minutes before serving. Garnish with fresh parsley and serve warm.