diff --git src/wp-admin/admin.php src/wp-admin/admin.php
index 1040995..c93e553 100644
--- src/wp-admin/admin.php
+++ src/wp-admin/admin.php
@@ -88,6 +88,38 @@ set_screen_options();
 $date_format = get_option('date_format');
 $time_format = get_option('time_format');
 
+wp_enqueue_script( 'wp-util' );
+
+add_filter( 'removable_url_params', function( $removable_url_params ) {
+	$my_params = array( 'mdub' );
+	return array_merge( $my_params, $removable_url_params );
+});
+$removable_url_params = array(
+	'user_switched',
+	'switched_off',
+	'switched_back',
+	'message',
+	'updated',
+	'settings-updated',
+	'saved',
+	'activated',
+	'activate',
+	'deactivate',
+	'locked',
+	'skipped',
+	'deleted',
+	'trashed',
+	'untrashed',
+);
+/**
+ * Filter the list of URL parameters to dynamically remove.
+ * 
+ * @since 4.2.0
+ *   
+ * @param array $removable_url_params An array of parameters to remove from the URL.
+ */
+$removable_url_params = apply_filters( 'removable_url_params', $removable_url_params );
+wp_localize_script( 'common', 'removableQueryArgs', $removable_url_params );
 wp_enqueue_script( 'common' );
 
 // $pagenow is set in vars.php
diff --git src/wp-admin/js/common.js src/wp-admin/js/common.js
index bcdb576..4b54c11 100644
--- src/wp-admin/js/common.js
+++ src/wp-admin/js/common.js
@@ -838,8 +838,44 @@ $(document).ready( function() {
 		}
 	};
 
+	/**
+	 * Remove parameters from admin pages after they're loaded so they don't trigger
+	 * messages again if the page is refreshed.
+	 * 
+	 * This relies on history.replaceState, so is not available to IE < 10 without a polyfill.
+	 * 
+	 * @link https://core.trac.wordpress.org/ticket/23367
+	 * @link http://caniuse.com/#search=pushstate
+	 * 
+	 * @since 4.2.0
+	 */
+	function removeQueryArgsFromUrl() {
+		/**
+		 * The list of parameters to check against.
+		 *
+		 * @type {Array}
+		 */
+		var removableQueryArgs = window.removableQueryArgs || [],
+		/**
+		 * The filtered URL.
+		 *
+		 * @type {string}
+		 */
+			url;
+
+		// Create the wpUrlParams object.    
+		wp.url.parseQueryArgs();
+
+		url = wp.url.removeQueryParam( removableQueryArgs );
+
+		if ( typeof history.replaceState === 'function' ) {
+			history.replaceState( null, null, url );
+		}
+	}
+
 	window.wpResponsive.init();
 	setPinMenu();
+	removeQueryArgsFromUrl(); 
 
 	$document.on( 'wp-window-resized.pin-menu postboxes-columnchange.pin-menu postbox-toggled.pin-menu wp-collapse-menu.pin-menu wp-scroll-start.pin-menu', setPinMenu );
 });
diff --git src/wp-includes/js/wp-util.js src/wp-includes/js/wp-util.js
index 1985b35..4eefe33 100644
--- src/wp-includes/js/wp-util.js
+++ src/wp-includes/js/wp-util.js
@@ -109,4 +109,144 @@ window.wp = window.wp || {};
 		}
 	};
 
+	/**
+	 * Tools for retrieving and manipulating URLs.
+	 * 
+	 * @since 4.2.0
+	 * 
+	 * @type {{removeQueryParam: Function, parseQueryArgs: Function}}
+	 */
+	wp.url = {
+		/**
+		 * Remove a parameter from a URL query string.
+		 *
+		 * To avoid certain messages from being displayed more than once (like when a
+		 * page is refreshed and a message is displayed based on the `msg=nnn` param),
+		 * you can use this to strip out a whitelisted array of parameters.
+		 *
+		 * @since 4.2.0
+		 *
+		 * @param {Array}  [removableQueryArgs] Optional. The parameter names to remove.
+		 * @param {String} [sourceURL]          Optional. The URL to parse; defaults to current URL.
+		 * @returns {String} The URL with the filtered parameters.
+		 */
+		removeQueryParam: function ( /* removableQueryArgs, sourceURL */ ) {
+			/**
+			 * The list of parameters to remove.
+			 * 
+			 * @type {Array}
+			 */
+			var removableQueryArgs = arguments[0] || window.removableQueryArgs,
+			/**
+			 * The URL to parse.
+			 * 
+			 * @type {String|Window.location.href}
+			 */
+				sourceURL = arguments[1] || window.location.href,
+			/**
+			 * The base URL.
+			 * 
+			 * @type {string}
+			 */
+				rtn = sourceURL.split( '?' )[0],
+			/**
+			 * The query string of the URL (param=val).
+			 * 
+			 * @type {string}
+			 */
+			    queryString = ( sourceURL.indexOf( '?' ) !== - 1 ) ? sourceURL.split( '?' )[1] : '',
+			/**
+			 * A map of the query string.
+			 * 
+			 * @type {Object}
+			 */
+			    params = window.wpUrlParams || wp.url.parseQueryArgs( sourceURL ),
+			/**
+			 * The filtered parameters in an array of strings.
+			 * 
+			 * @type {string[]}
+			 */
+			    newParams = [];
+
+			if ( '' !== queryString ) {
+				_.reject( params, function( param, index ) {
+					if( ! _.contains( removableQueryArgs, index ) ) {
+						newParams.push( index + '=' + param );
+					}
+				});
+			}
+			
+			return rtn + '?' + newParams.join( '&' );
+		},
+
+		/**
+		 * Parse the query string from a URL into an object of param:value.
+		 * 
+		 * @since 4.2.0
+		 * 
+		 * @param {String} [url] Optional. Defaults to current URL if not set.
+		 * @returns {Object} The extracted parameters.
+		 */
+		parseQueryArgs: function ( /* url */ ) {
+			/**
+			 * The URL to parse.
+			 * 
+			 * @type {*|Window.location.href}
+			 */
+			var url = arguments[0] || window.location.href,
+			/**
+			 * The URL query string.
+			 * 
+			 * @type {string}
+			 */
+			    queryString = ( - 1 !== url.indexOf( '?' ) ) ? url.split( '?' )[1] : '',
+			/**
+			 * A collection of parameters and their values as strings.
+			 * 
+			 * @type {Array}
+			 */
+			    params = [],
+			/**
+			 * A collection of parameters and their values.
+			 * 
+			 * @type {Object.<string, string>}
+			 */
+			    argMap = {},
+			/**
+			 * The filtered {@link argMap}.
+			 * 
+			 * @type {Object.<string, string>}
+			 */
+			    filteredArgMap = {};
+
+			if ( '' !== queryString ) {
+				params = queryString.split( '&' );
+				_.each( params, function ( param ) {
+					/**
+					 * An array containing the the param[0] and value[1].
+					 * 
+					 * @type {Array}
+					 */
+					var p = param.split( '=' );
+					argMap[ p[0] ] = p[1];
+				} );
+			}
+			
+			// Filter the object so it only contains our declared values,
+			// and not inherited ones from the Object prototype.
+			for ( var arg in argMap ) {
+				if ( argMap.hasOwnProperty( arg ) ) {
+					filteredArgMap[arg] = argMap[arg];
+				}
+			}
+			
+			/**
+			 * Make the params available to the DOM.
+			 * 
+			 * @global
+			 * @type {Object.<string, string>}
+			 */
+			return window.wpUrlParams = filteredArgMap;
+		}
+	};
 }(jQuery));
diff --git tests/qunit/wp-admin/js/common-remove-querystring-args.js tests/qunit/wp-admin/js/common-remove-querystring-args.js
new file mode 100644
index 0000000..87c96de
--- /dev/null
+++ tests/qunit/wp-admin/js/common-remove-querystring-args.js
@@ -0,0 +1,52 @@
+/* global wp */
+
+jQuery( function ( $ ) {
+	module( 'Remove QueryString Args: InList' );
+	var removableQueryArgs = [
+		'user_switched',
+		'switched_off',
+		'switched_back',
+		'message',
+		'updated',
+		'settings-updated',
+		'saved',
+		'activated',
+		'activate',
+		'deactivate',
+		'locked',
+		'skipped',
+		'deleted',
+		'trashed',
+		'untrashed'
+	];
+
+	function removeParam( key, sourceURL ) {
+		var rtn = sourceURL.split( '?' )[0], param, params = [],
+		    queryString = (sourceURL.indexOf( '?' ) !== - 1) ? sourceURL.split( '?' )[1] : '';
+		if ( queryString !== '' ) {
+			params = queryString.split( '&' );
+			for ( var i = params.length - 1; i >= 0; i -= 1 ) {
+				param = params[i].split( '=' )[0];
+				if ( $.inArray( param, key ) > - 1 ) {
+					params.splice( i, 1 );
+				}
+			}
+			rtn = rtn + '?' + params.join( '&' );
+		}
+		return rtn;
+	}
+
+	test( 'should remove listed arg from the URL', function () {
+		var testUrl = 'http://src.wordpress-develop.dev/wp-admin/plugins.php?deactivate=true&plugin_status=all&paged=1&s=',
+		    finalUrl = 'http://src.wordpress-develop.dev/wp-admin/plugins.php?plugin_status=all&paged=1&s=';
+
+		equal( removeParam( removableQueryArgs, testUrl ), finalUrl, 'deactivate removed from URL' );
+	} );
+
+	test( 'should not remove unlisted arg from the URL', function () {
+		var testUrl = 'http://src.wordpress-develop.dev/wp-admin/plugins.php?deactivated=true&plugin_status=all&paged=1&s=',
+		    finalUrl = 'http://src.wordpress-develop.dev/wp-admin/plugins.php?deactivated=true&plugin_status=all&paged=1&s=';
+
+		equal( removeParam( removableQueryArgs, testUrl ), finalUrl, 'deactivated not removed from URL' );
+	} );
+} );
\ No newline at end of file
