I couldn't get this to work as described above.
The format that worked for my requirement - filtering IDs not in an array - is as follows:
(ID ne '289') and (ID ne '176') and (ID ne '192') and ...
i.e. each condition is enclosed in parentheses.
To build this up and because I can never remember how to correctly escape characters, I created compose steps for each weird character:

Then a final compose step brings them together, which is the same as @badri123's method above :
concat(outputs('lbr'),'ID ne ',outputs('quote'), join(variables('varArray'), concat(outputs('quote'),outputs('rbr'),' and ',outputs('lbr'),'ID ne ',outputs('quote'))),outputs('quote'),outputs('rbr'))The compose output then goes straight into the Odata filter query
