get_post_types – exclude multiple post types by name

The query args you’re passing to get_post_types() are handled by the underlying function wp_filter_object_list(), which isn’t designed to handle advanced querying operations like “if key value (not) in array”.

Since you’re just getting the names of post types, use the native PHP function array_diff to filter the out the ones you don’t want:

$post_types = array_diff( get_post_types(), [ 'page', 'attachment' ] );

FWIW, if you were getting post type objects, you could use array_filter with something like:

$post_type_objects = array_filter( get_post_types( [], 'objects' ), function ( $post_type_object ) {
    return ! in_array( $post_type_object->name, [ 'page', 'attachment' ] );
});