diff --git a/manifests/serial/auto.pp b/manifests/serial/auto.pp
new file mode 100644
index 0000000000000000000000000000000000000000..5417d8b69fb7127d1b0d8d7b0270c6d977c6b98f
--- /dev/null
+++ b/manifests/serial/auto.pp
@@ -0,0 +1,85 @@
+# Copyright © 2021   Thomas Bellman, Linköping, Sweden
+# Licensed under the GNU LGPL v3+; see the README file for more information.
+
+
+/*
+ * Try to guess which serial ports to enable getty on, and which to
+ * disable on.
+ *
+ * Parameters:
+ *  - enable_ports
+ *  - disable_ports
+ *  - possible_ports
+ *  - getty_options
+ *  - speeds
+ *  - termtype
+ *
+ * Default values for these are taken from the console::serial::config class.
+ *
+ * The intent is that most nodes should be able to do just
+ *
+ *     include console::serial::auto
+ *
+ * while nodes needing special handling can do e.g.
+ *
+ *     class { console::serial::auto: enable_ports => ['ttyS17']; }
+ *
+ * to override the guessing.
+ */
+class console::serial::auto(
+	$enable_ports	= $console::serial::config::enable_ports,
+	$disable_ports	= $console::serial::config::disable_ports,
+	$possible_ports	= $console::serial::config::possible_ports,
+	$getty_options	= $console::serial::config::getty_options,
+	$speeds		= $console::serial::config::speeds,
+	$termtype	= $console::serial::config::termtype,
+)
+     inherits console::serial::config	# To get the params defaults
+{
+    $osdist = "${::operatingsystem}-${::operatingsystemrelease}"
+
+    if ($enable_ports != undef  and  $enable_ports != false) {
+	$x_enableports = $enable_ports
+    } elsif ($osdist =~ /^(CentOS|Redhat|Scientific)-6(\.|$)/) {
+	$x_enableports = $::virtual ? {
+	    'physical'	=> [ 'ttyS0', ],
+	    'xen0'	=> [ 'hvc0', ],
+	    'xenu'	=> [ 'hvc0', ],
+	    'xenhvm'	=> [ 'ttyS0', ],
+	    default	=> fail("${name}: Unsupported virtualization"),
+	}
+    } elsif ($osdist =~ /^(CentOS|Redhat|Scientific)-7(\.|$)/) {
+	$x_enableports = $::virtual ? {
+	    'physical'	=> [ 'ttyS0', ],
+	    'xen0'	=> [ 'hvc0', ],
+	    'xenu'	=> [ 'xvc0', ],
+	    'xenhvm'	=> [ 'ttyS0', ],
+	    default	=> fail("${name}: Unsupported virtualization"),
+	}
+    } else {
+	fail("${name}: Unsupported operating system")
+    }
+
+    if ($disable_ports != undef  and $disable_ports != false) {
+	$x_disableports = $disable_ports
+    } else {
+	$x_disableports = split(inline_template(
+	    '<%= [@possible_ports].flatten.reject {|port|
+		     [@x_enableports].flatten.include?(port)
+		 }.join("|")
+	     %>'),
+	    "[|]")
+    }
+
+    console::serial::login {
+	$x_enableports:
+	    ensure => 'enabled',
+	    rootlogin => 'allow',
+	    getty_options => $getty_options,
+	    speeds => $speeds,
+	    termtype => $termtype;
+
+	$x_disableports:
+	    ensure => 'disabled', rootlogin => 'forbid';
+    }
+}
diff --git a/manifests/serial/config.pp b/manifests/serial/config.pp
index 445e751c32dbfd9d9278cab92fc2d552a4158a12..2c7915931cff62d26b390b70492542e56cd622ae 100644
--- a/manifests/serial/config.pp
+++ b/manifests/serial/config.pp
@@ -20,6 +20,24 @@ class console::serial::config(
 	# Default terminal type connected to ports
 	#
 	$termtype = 'vt100',
+
+
+	#####  Parameters specific to console::serial::auto  ###########
+
+	# Ports to enable getty on.  The default is to guess this list; the
+	# guessed list will typically only be a single port.
+	#
+	$enable_ports=undef,
+
+	# Ports to disable getty on.  The default is to compute this as the
+	# set difference between $possible_ports and $enable_ports.
+	#
+	$disable_ports=undef,
+
+	# List of ports where a getty might need to be disabled.  This is
+	# only used if $disable_ports is not set.
+	#
+	$possible_ports=[ 'ttyS0', 'ttyS1', 'hvc0', 'xvc0', ],
 )
 {
     # Empty class