Preheat the oven to 375 degrees Fahrenheit. Lightly grease a 9×13-inch casserole dish with cooking spray and set aside.
First, peel the potatoes. Then, use a mandoline slicer (the easiest method) or a sharp chef’s knife to slice the potatoes so they are about ⅛-inch thick. Transfer the sliced potatoes to a large bowl filled with cold water. Once all of the potatoes have been sliced, drain and pat them dry with paper towels. Set aside. Note: If you are using Russet potatoes, it is especially important to rinse them with cold water to remove excess starch and prevent them from turning an orangish, rusting color.
Melt the butter in a medium saucepan. Once melted, whisk in the flour until thoroughly combined and golden (about 2 minutes).
Increase the heat to medium-high and slowly add the milk, whisking the entire time. Once simmering (do not boil), reduce the heat to low and continue whisking until thickened (about 3-5 minutes). Note: If the sauce is too thick, thin it with a bit of chicken broth. Start with 1/4 cup and add more from there.
Remove from the heat and stir in the chicken bouillon, salt, and pepper. Once combined, stir in both cheeses until melted and fully incorporated with the sauce.
To assemble, layer 1/3 of the potatoes over the bottom of the prepared casserole dish and top with 1/2 of the ham, followed by 1/3 of the sauce. Repeat with 1/3 of the potatoes, the rest of the ham, and 1/3 of the cheese sauce. Finally, top with the remaining potatoes, followed by the remaining cheese sauce. Optional: Sprinkle with additional shredded cheese or breadcrumbs, if desired.
Cover with foil and bake for 45 minutes, then remove the foil and bake, uncovered, for 20-30 minutes, or until the top is golden and the potatoes are tender.
Remove from the oven and allow the casserole to rest for 10 minutes before serving. Garnish with freshly chopped chives or green onions, if desired.