Architecture for Powerup system

Options
I have a 4 player multiplayer race where players can use various powerups that help them, hurt others or generally affect the environment. I have it all working but I'm trying to improve the architecture so its easier to add new powerups. Does anyone have advice or an example of such a system?

Here's what I have:
Player 1 uses a shield powerup. I instantiate a "shieldpowerup" PunBehaviour object in the scene that displays the shield on player 1 locally. This network object runs an RPC which displays the shield on player 1 on all remote clients.
When player 1's powerup finishes, it sends another RPC asking other clients to disable/end the powerup and destroy the network object.

I wanted to see if I could do the same without instantiating a network object for each powerup, so I tried creating a single Powerup Controller network object. The controller communicates with all clients when a powerup is started and sends a powerup name and sender ID to all clients. Each powerup implements appropriate functions that runs local and remote.
The problem I have with this architecture is that its harder to synchronize the ending of each powerup since its not controlled from their own network object. (i.e. the controller has to control all the active powerups in the system).

Phew, that probably made no sense. Basically looking for a neat extensible powerup system with good performance.