ULX does support targeting by any type of IDs you like using the '$' operator:
... '$<userid>' to target by ID (steamid, uniqueid, userid, ip) ...
So, something like the following should work:
RunConsoleCommand("ulx","slay", "$" .. tar:SteamID())
However, if someone else were to set their name to be (for example) "$STEAM_0:1:<your_steam_id>", this would still cause a conflict. This is where ULib.getUniqueIDForPlayer( ply ) comes in. It's not really clear, but this function basically returns any type of a player's ID that does not conflict with another player's name or ID. It will return one of the following (I think in this order): UniqueID, IP address, SteamID, or UserID (seen in sv_status).
As noted in the docs, this data is best fed into ULib.getUser(s), or into the $ operator in a targeting string.
So, to use that in your example would look like this:
RunConsoleCommand("ulx","slay", "$" .. ULib.getUniqueIDForPlayer(tar))
One final note, the reason why you're getting a lot of conflicts with names and multiple targets found might have to do with RunConsoleCommand and splitting args on spaces- Due to how ULX commands are set up, you might have to split the name by spaces, then pass each segment as an additional argument to RunConsoleCommand.