diff --git a/src/bin/pg_ctl/pg_ctl.c b/src/bin/pg_ctl/pg_ctl.c
index 6a36d29..07345d8 100644
--- a/src/bin/pg_ctl/pg_ctl.c
+++ b/src/bin/pg_ctl/pg_ctl.c
@@ -73,6 +73,15 @@ typedef enum
 	RUN_AS_SERVICE_COMMAND
 } CtlCommand;
 
+#if defined(WIN32) || defined(__CYGWIN__)
+typedef enum
+{
+	WinLogOutput_default,
+	WinLogOutput_stderr,
+	WinLogOutput_eventlog
+} WinLogOutput;
+#endif
+
 #define DEFAULT_WAIT	60
 
 static bool do_wait = false;
@@ -110,6 +119,7 @@ static SERVICE_STATUS status;
 static SERVICE_STATUS_HANDLE hStatus = (SERVICE_STATUS_HANDLE) 0;
 static HANDLE shutdownHandles[2];
 static pid_t postmasterPID = -1;
+static WinLogOutput log_output = WinLogOutput_default;
 
 #define shutdownEvent	  shutdownHandles[0]
 #define postmasterProcess shutdownHandles[1]
@@ -212,10 +222,11 @@ write_stderr(const char *fmt,...)
 #else
 
 	/*
-	 * On Win32, we print to stderr if running on a console, or write to
-	 * eventlog if running as a service
+	 * On Win32, we write to eventlog if eventlog is enforced or running as a service,
+	 * otherwise write to stderr
 	 */
-	if (!isatty(fileno(stderr)))	/* Running as a service */
+	if (log_output == WinLogOutput_eventlog /* eventlog is enforced */
+		|| (log_output == WinLogOutput_default && !isatty(fileno(stderr))))	/* or running as a service */
 	{
 		char		errbuf[2048];		/* Arbitrary size? */
 
@@ -224,7 +235,7 @@ write_stderr(const char *fmt,...)
 		write_eventlog(EVENTLOG_ERROR_TYPE, errbuf);
 	}
 	else
-		/* Not running as service, write to stderr */
+		/* stderr is enforced or not running as a service, write to stderr */
 		vfprintf(stderr, fmt, ap);
 #endif
 	va_end(ap);
@@ -1927,6 +1938,16 @@ do_help(void)
 	printf(_("(The default is to wait for shutdown, but not for start or restart.)\n\n"));
 	printf(_("If the -D option is omitted, the environment variable PGDATA is used.\n"));
 
+#if defined(WIN32) || defined(__CYGWIN__)
+	printf(_("\nCommon options for logging errors:\n"));
+	printf(_("  --log-output=OUT       OUT can be \"default\", \"stderr\", or \"eventlog\"\n"));
+	printf(_("\nLog outputs are:\n"));
+	printf(_("  default    log errors to Windows Event Log if running as a service,\n"
+	         "             otherwise log to stderr\n"));
+	printf(_("  stderr     log errors to stderr\n"));
+	printf(_("  eventlog   log errors to Windows Event Log\n"));
+#endif
+
 	printf(_("\nOptions for start or restart:\n"));
 #if defined(HAVE_GETRLIMIT) && defined(RLIMIT_CORE)
 	printf(_("  -c, --core-files       allow postgres to produce core files\n"));
@@ -2104,6 +2125,12 @@ adjust_data_dir(void)
 	canonicalize_path(pg_data);
 }
 
+typedef enum
+{
+#if defined(WIN32) || defined(__CYGWIN__)
+	OptionLogOutput = 1000
+#endif
+} LongOnlyOption;
 
 int
 main(int argc, char **argv)
@@ -2117,6 +2144,9 @@ main(int argc, char **argv)
 		{"silent", no_argument, NULL, 's'},
 		{"timeout", required_argument, NULL, 't'},
 		{"core-files", no_argument, NULL, 'c'},
+#if defined(WIN32) || defined(__CYGWIN__)
+		{"log-output", required_argument, NULL, OptionLogOutput},
+#endif
 		{NULL, 0, NULL, 0}
 	};
 
@@ -2266,6 +2296,20 @@ main(int argc, char **argv)
 				case 'c':
 					allow_core_files = true;
 					break;
+#if defined(WIN32) || defined(__CYGWIN__)
+				case OptionLogOutput:
+					if (strcmp(optarg, "default") == 0)
+						log_output = WinLogOutput_default;
+					else if (strcmp(optarg, "stderr") == 0)
+						log_output = WinLogOutput_stderr;
+					else if (strcmp(optarg, "eventlog") == 0)
+						log_output = WinLogOutput_eventlog;
+					else {
+						do_advice();
+						exit(1);
+					}
+					break;
+#endif
 				default:
 					/* getopt_long already issued a suitable error message */
 					do_advice();
