Try:
(~/home/partner/onboard/)(.*)(/.+\.[^?]+)((\?)(.*))?
with the 'ignore case' option on.
As you presented your pattern, you would not get a match without the 'ignore case' because the pattern was looking for the literal text "nboard" but the examples had the 'B' capitalised. If you were using 'ignore case' then you don't need the "[Oo]" subpattern.
To make the last part optional, I have added another set of parentheses to make it "((\?)(.*))?". This means that the whole '?param=2' part can either be there or missing. Note that you now have 6 match groups and that you want to look at match groups #5 and #6 instead of #4 and #5 as before. (Of course you can use the fact that #4 will still be null if both #5 and #6 are null)
HOWEVER, because it can be missing and just before it you had '.+' in the pattern, this was grabbing everything to the end of the string in all cases and always leaving the (now) optional part unused. Your original pattern relied on backtracking when looking for the ?, but it is now optional and so cannot be relied on. There are two solutions to this, one of which I have presented above - scan forward accepting everything EXCEPT a ?; if you find one then the optional subpattern that follows will be used, if not then you must have found the end of the string/line (depending on the multiline option setting) and the optional tailer will be skipped.
The other way is to use a non-greedy option:
(~/home/partner/onboard/)(.*)(/.+\..+?)((\?)(.*))?
but you have not mentioned the regex/programming language you are using and so I have no idea if this is possible.
Susan