Articles

Tuesday, December 11, 2012

How to determine if Windows was shutdown or rebooted


An user on FreeNode recently asked a question regarding how he can run a backup script only if the system is shutting down. At the face of it, it sounds simple, use a shutdown script like people have for years, but the keyword here is only. He needed to be able to run a script if the system was sent a shutdown event, but not run the script if the system was rebooted. This throws a wrench into using a shutdown script because a shutdown script runs regardless of whether the system is rebooted or shutdown. When an application or user initiates a shutdown Windows will write an event to the Event Viewer System log. The event originates from the USER32 event source with an Event ID of 1074. A typical 1074 event looks like this:

<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
- <System>
  <Provider Name="USER32" /> 
  <EventID Qualifiers="32768">1074</EventID> 
  <Level>4</Level> 
  <Task>0</Task> 
  <Keywords>0x80000000000000</Keywords> 
  <TimeCreated SystemTime="2012-12-05T01:34:03.000000000Z" /> 
  <EventRecordID>6649</EventRecordID> 
  <Channel>System</Channel> 
  <Computer>computer.domain.local</Computer> 
  <Security UserID="S-1-5-21-2671312382-3219971570-2213343823-1105" /> 
  </System>
- <EventData>
  <Data>C:\Windows\system32\shutdown.exe (COMPUTERNAME)</Data> 
  <Data>COMPUTERNAME</Data> 
  <Data>No title for this reason could be found</Data> 
  <Data>0x800000ff</Data> 
  <Data>restart</Data> 
  <Data /> 
  <Data>DOMAIN\username</Data> 
  <Binary>FF000080000000000000000000000000000000000000000000000000000000000000000000000000</Binary> 
  </EventData>
  </Event>

This is the XML view of the event data generated by a reboot request. The part we are interested in is under the EventData node, where it says restart. If it was a shutdown event that was initiated it would say shutdown rather than restart. This is perfect as we now have a way to determine whether or not the system was sent a shutdown or restart request. So how can we get this data programatically via our shutdown script? Simple, we can use the wevtutil utility that ships with Windows Vista and up. The help context for the utility is quite lengthy so I won't post it all here, but you can open a Command Prompt and run wevtutil /? to see all the options. The wevtutil can make use of XPath queries for querying the XML output of an event. We can use an XPath query to query only for the data we need to check whether or not the system was sent a shutdown or restart. The following command will grab all the 1074 events from the USER32 source in the System event log:


C:\>wevtutil qe system /f:text /q:"*[System/EventID=1074]"
Event[0]:
  Log Name: System
  Source: USER32
  Date: 2012-10-05T01:10:59.000
  Event ID: 1074
  Task: N/A
  Level: Information
  Opcode: N/A
  Keyword: Classic
  User: S-1-5-18
  User Name: NT AUTHORITY\SYSTEM
  Computer: computername
  Description:
The process C:\Windows\system32\winlogon.exe (COMPUTERNAME) has initiated the restart of computer COMPUTERNAME on be
half of user NT AUTHORITY\SYSTEM for the following reason: Operating System: Upgrade (Planned)
 Reason Code: 0x80020003
 Shutdown Type: restart
 Comment:

Event[1]:
  Log Name: System
  Source: USER32
  Date: 2012-10-04T18:55:14.000
  Event ID: 1074
  Task: N/A
  Level: Information
  Opcode: N/A
  Keyword: Classic
  User: S-1-5-18
  User Name: NT AUTHORITY\SYSTEM
  Computer: computername
  Description:
The process C:\Windows\System32\shutdown.exe (COMPUTERNAME) has initiated the restart of computer COMPUTERNAME on behalf of u
ser NT AUTHORITY\SYSTEM for the following reason: No title for this reason could be found
 Reason Code: 0x800000ff
 Shutdown Type: restart
 Comment:

...

We use the /f switch here to specify that the output should be in plain text as it defaults to XML. So now we can query for the events we need, but we need a way to sort them and to only grab the last event. We can use the /c and /rd switches to do this. The /c switch takes an unsigned integer as a parameter that tells wevtutil how many events to return. The /rd switch takes a boolean and tells wevtutil do sort them in reverse direction. Now our command looks like this:

C:\>wevtutil qe system /c:1 /rd:true /f:text /q:"*[System/EventID=1074]"
Event[0]:
  Log Name: System
  Source: USER32
  Date: 2012-12-04T19:34:03.000
  Event ID: 1074
  Task: N/A
  Level: Information
  Opcode: N/A
  Keyword: Classic
  User: S-1-5-21-2671312382-3219971570-2213343823-1105
  User Name: DOMAIN\username
  Computer: computer.domain.local
  Description:
The process C:\Windows\system32\shutdown.exe (WIN7) has initiated the restart of computer WIN7 on behalf of user DOMAIN\username for the following reason: No title for this reason could be found
 Reason Code: 0x800000ff
 Shutdown Type: restart
 Comment:

Now all we have to do is parse out the Shutdown Type which is made simple with the for command:


C:\>for /f "tokens=3 delims= " %i in ('wevtutil qe system /c:1 /rd:true /f:text /q:"*[System/EventID=1074]" ^| findstr /c:"Shutdown Type"') do @echo %i
restart

C:\>

Now that we have parsed out the shutdown type we can set it to a variable and then run conditional code based on the value of the variable.

@echo off
for /f "tokens=3 delims= " %%i in ('wevtutil qe system /c:1 /rd:true /f:text /q:"*[System/EventID=1074]" ^| findstr /c:"Shutdown Type"') do (
    set shutdownType=%%i
)
if ["%shutdownType%"]==["shutdown"] (
    :: your shutdown code here
) else (
    :: if not a shutdown, do something else
)

Just to be safe we can make sure the event we are grabbing is the event that was just initiated by using the XPath timediff() function. This will make sure the event was initiated within the last 60 seconds, specified in milliseconds:

@echo off
for /f "tokens=3 delims= " %%i in ('wevtutil qe system /c:1 /rd:true /f:text /q:"*[System/EventID=1074] and TimeCreated[timediff(@SystemTime) >= 60000]" ^| findstr /c:"Shutdown Type"') do (
    set shutdownType=%%i
)
if ["%shutdownType%"]==["shutdown"] (
    :: your shutdown code here
) else (
    :: if not a shutdown, do something else
)

Saturday, December 1, 2012

Joining Windows Server 2012 Core to a domain

You can use the netdom utility to join a Windows Server 2012 Core of Full server to a domain.

>netdom join %computername% /domain:yourdomain.local /userd:<DomainAdmin> /passwordd: /reboot:0

If you're using the PowerShell console substitute %computername% with $env:computername.

Changing the hostname on Windows Server 2012

Use the following commands to change the hostname on a Windows Server 2012 Core or Full server from the command line. This can be done with either the Command Prompt or PowerShell console:

Change the hostname from the Command Prompt

> netdom renamecomputer %computername% /newname:<NewName> /reboot:0

Change the hostname from the PowerShell console

> netdom renamecomputer $env:computername /newname:<NewName> /reboot:0


You will be warned that certain services such as Active Directory Certificate Services may not function correctly after changing the hostname. If you do not want to reboot the system immediately omit the /reboot switch. To reboot the server a later time use shutdown -r -t 0.

Adding and removing the GUI from Windows Server 2012

Microsoft introduced the ability to add and remove the GUI from Windows Server 2012 in case you find yourself lost with only a Command Prompt for administration and configuration of your servers. If you do a Core installation of Windows Server 2012 and want to add the full GUI back to your server you can use the Install-WindowsFeature cmdlet to install it.

To install the full GUI

> Install-WindowsFeature Server-Gui-Mgmt-Infra, Server-Gui-Shell -Restart

To uninstall the GUI from a full installation of Windows Server 2012

> Uninstall-WindowsFeature Server-Gui-Mgmt-Infra, Server-Gui-Shell -Restart

You may be wondering why you would ever want to uninstall the GUI? A good scenario is that you want to configure your server initially using the graphical tools, and after it's full configured, you want to reduce the footprint and attack surface of your server.


Friday, November 30, 2012

Windows Server 2012 - Renaming Network Interfaces from the Command Line

Every since I started using Linux as my primary desktop OS I've gotten used to configuring network settings from the command line. Linux names network interfaces according to what type of interface they are, ethernet, wireless, tunnel, etc, using the naming convention ethX, wlanX, tunX, where X is an incremental integer.

By default in Windows Server 2012 ethernet adapters have the name Ethernet, which to me is too much to type when configuring network settings on a Windows server from the command line with netsh. You can rename your interfaces using the following commands in Windows:

Get a list of current interfaces on the system:

>netsh int show interface

Admin State    State          Type             Interface Name
-------------------------------------------------------------------------
Enabled        Connected      Dedicated        Ethernet


Rename the interface using the Linux naming convention:

>netsh int set interface name="Ethernet" newname=eth0

Enabling RDP on Windows Server 2012 Core


Because the Core editions of Windows Server have no GUI we can't use the Server Manager (at least locally) to enable connections over RDP to the Windows Core host. To get around that Microsoft includes a WSH script with the Core editions that can run from the Command Prompt. Use the following command to enable RDP on your Core servers.

cd \windows\system32
cscript scregedit.wsf /AR 0

You can use the /v switch to check the state of the RDP setting. If it shows 1, RDP connections are not enabled, if it's 0 they are.

Below is a list of all the options for the scregedit.wsf script:

Microsoft (R) Windows Script Host Version 5.8
Copyright (C) Microsoft Corporation. All rights reserved.

Automatic Updates - Manage Automatic Windows Updates
These settings can be used to configure how Automatic Updates are applied to
the Windows system. It includes the ability to disable automatic updates and
to set the installation schedule.

/AU [/v][value]

/v View the current Automatic Update settings
value value you want to set to.

Options:
4 - Enable Automatic Updates
1 - Disable Automatic Updates


Terminal Service - Allow Remote Administration Connections
This allows administrators to connect remotely for administration purposes.

/AR [/v][value]

/v View the Remote Terminal Service Connection setting
value (0 = enabled, 1 = disabled)


Terminal Service - Allow connections from previous versions of Windows
This setting configures CredSSP based user authentication for
Terminal Service connections

/CS  [/v][value]

/v View the Terminal Service CredSSP setting
value (0 = allow previous versions, 1 = require CredSSP)


IP Security (IPSEC) Monitor - allow remote management
This setting configures the server to allow the IP Security (IPSEC) Monitor to
be able to remotely manage IPSEC.

/IM [/v][value]

   /v View the IPSEC Monitor setting
value (0 = do not allow, 1 = allow remote management)


DNS SRV priority - changes the priority for DNS SRV records
This setting configures the priority for DNS SRV records and is only useful
on Domain Controllers.
For more information on this setting, search TechNet for LdapSrvPriority

/DP [/v][value]

   /v View the DNS SRV priority setting
value (value from 0 through 65535. The recommended value is 200.)


DNS SRV weight - changes the weight for DNS SRV records
This setting configures the weight for DNS SRV records and is only useful
on Domain Controllers.
For more information on this setting, search TechNet for LdapSrvWeight

/DW [/v][value]

   /v View the DNS SRV weight setting
value (value from 0 through 65535. The recommended value is 50.)


Command Line Reference
This setting displays a list of common tasks and how to perform them from
the command line.

/CLI

Thursday, October 4, 2012

Compiling Server Status Widget on Kubuntu 12.04

Recently I found a cool little widget for KDE4 called Server Status. It allows you to monitor systems, servers, or anything else with an IP address or hostname. I had some issues getting it to compile under Kubuntu 12.04 so I thought I'd leave some documentation here in case anyone else runs into the same issues I did.

Here are the steps to get it compiled and working:

git clone git://gitorious.org/serverstatuswidget/serverstatuswidget.git

cd /serverstatuswidget
sudo apt-get install build-essential libqt4-core qt4-qmake libqt4-dev libqt4-gui kdelibs5-dev
cmake -DCMAKE_INSTALL_PREFIX=$(kde4-config --prefix)
sudo make
sudo make install 
kbuildsycoca4

Friday, August 17, 2012

Disabling vsync on Intel Integrated HD graphics with driconf

First install driconf:

sudo apt-get install driconf

Then run driconf from a shell, enable Expert Mode, and set the synchronize with vertical refresh to Never. Then under Image Quality settings enable  S3TC. Hit save.

Then add the following to your ~/.drirc:

      <device screen="0" driver="dri2">
          <application name="Default">
              <option name="vblank_mode" value="0" />
          </application>
      </device>

Your drirc should look like the following when you're done:

<driconf>
      <device screen="0" driver="dri2">
          <application name="Default">
              <option name="vblank_mode" value="0" />
          </application>
      </device>
      <device screen="0" driver="i965">
          <application name="Default">
              <option name="force_s3tc_enable" value="true" />
              <option name="no_rast" value="false" />
              <option name="always_flush_cache" value="false" />
              <option name="stub_occlusion_query" value="false" />
              <option name="always_flush_batch" value="false" />
              <option name="bo_reuse" value="1" />
              <option name="texture_tiling" value="true" />
              <option name="early_z" value="false" />
              <option name="allow_large_textures" value="2" />
              <option name="fragment_shader" value="false" />
          </application>
      </device>
</driconf>

To test if it worked run glxgears and you should see your FPS in the thousands, way above your monitors refresh rate:

16233 frames in 5.0 seconds = 3246.366 FPS
17469 frames in 5.0 seconds = 3493.649 FPS

Thursday, August 16, 2012

Installing the Intel HD integrated graphics drivers on Linux

To get the Intel HD x000 drivers working in Linux do the following:

sudo apt-add-repository ppa:glasen/intel-driver
sudo apt-get update && sudo apt-get upgrade
sudo apt-get install xserver-xorg-video-intel
sudo init 6
 
I am using Kubuntu 12.04 x64 but any Ubuntu derivative should work.

Thursday, March 15, 2012

Get your public IP from the win32 command-line

Sometimes it's beneficial to be able to retrieve your public routable IP address via the command line so that you can use it in scripts. Using only native tools in Windows this is not possible. I do have an old script that uses a hybrid batch and VBScript solution that uses telnet to connect to a PHP script that dumps back the REMOTE_ADDR super global, but it was clunky and didn't always work reliably. Below is a hybrid batch and powershell script that can do it. Of course this could be done with only powershell, but I wrote it this way so I could use it in both powershell and batch scripts.

Here is the code:

@echo off
powershell -encodedcommand KABuAGUAdwAtAG8AYgBqAGUAYwB0ACAAcwB5AHMAdABlAG0ALgBuAGUAdAAuAHcAZQBiAGMAbABpAGUAbgB0ACkALgBkAG8AdwBuAGwAbwBhAGQAcwB0AHIAaQBuAGcAKAAiAGgAdAB0AHAAOgAvAC8AYwBoAGUAYwBrAGkAcAAuAGEAbAB0AGUAcgB2AGkAcwB0AGEALgBvAHIAZwAvAGkAcAAuAHAAaABwACIAKQA=

Here is the decoded base64 powershell code:

(new-object system.net.webclient).downloadstring("http://checkip.altervista.org/ip.php")


Tuesday, February 14, 2012

Getting Shrew Soft VPN Client Working on Ubuntu 11.10

I recently built a new pfSense router for my home lab. After getting everything up and running I set up an IPSec VPN so I could get secure access to my home lab from where ever I may be. Having never setup an IPSec VPN before, I wasn't sure which client people used. I searched Synaptic for "ipsec" and found one called Shrew Soft VPN Client. After Googling around a little more, I found that, that was a pretty commonly used client for IPSec VPN connections. I installed it via Synaptic, filled in all my settings and hit the connect button. Below was the output:


config loaded for site mysite
attached to key daemon ...
peer configured
iskamp proposal configured
esp proposal configured
ipcomp proposal configured
client configured
local id configured
remote id configured
pre-shared key configured
bringing up tunnel ...
negotiation timout occurred
tunnel disabled
detached from key daemon ...



After trying to connect a few times, and rechecking my settings on my pfSense box, I decided to Google around alternative clients. I tried using one called OpenSwan, and another called StrongSwan, that were both plugins for NetworkManager. Neither of them worked, so I was back to square one.

To make this work on Ubuntu 11.10 you need to use an older version, version 2.15 to be exact. To install it, do the following:

For x86 systems:

# wget http://mirror.pnl.gov/ubuntu//pool/universe/o/openssl098/libssl0.9.8_0.9.8o-7ubuntu1_i386.deb

# wget http://mirror.pnl.gov/ubuntu//pool/universe/i/ike/ike-qtgui_2.1.5+dfsg-2_i386.deb

# wget http://mirror.pnl.gov/ubuntu//pool/universe/i/ike/ike_2.1.5+dfsg-2_i386.deb

# dpkg -i *.deb


For x64 systems:

# wget http://security.ubuntu.com/ubuntu/pool/main/o/openssl/libssl0.9.8_0.9.8o-5ubuntu1.2_amd64.deb

# wget http://mirror.pnl.gov/ubuntu//pool/universe/i/ike/ike-qtgui_2.1.5+dfsg-2_amd64.deb

# wget http://mirror.pnl.gov/ubuntu//pool/universe/i/ike/ike_2.1.5+dfsg-2_amd64.deb

# dpkg -i *.deb

You can find it in your Internet menu.

dcprom0

Tuesday, January 10, 2012

CMD Shell tricks

Recently there was a post on the alt.msdos.batch.nt news group where someone needed to get an IP address into a variable. Sounds easy enough, but the problem he was having was that he couldn't use typical parsing with the findstr command because the language settings were not consistent between systems.

The easiest way to get your local IP address into a variable is like this:

# for /f "tokens=2 delims=[]:" %i in ('ping -n 1 -4 %computername% ^| findstr /i "pinging"') do set ip=%i& echo %ip%


This works fine most of the time, but what if you have multiple interfaces on your system? Consider this:



# for /f "tokens=2 delims=[]:" %i in ('ping -4 -n 1 %computername% ^| findstr /i
"pinging"') do set ip=%i& echo %ip%
169.254.238.27


#


What is that address? That's an APIPA address that Microsoft so graciously provided us in case we were unable to receive an IP address from a DHCP server. This isn't our actual IP address that we are using on the LAN, so this isn't the output we want.

Going back to our original problem, the findstr /i "pinging" won't work because the language was different. So, we need another way to determine this, while also maintaining backwards compatibility with older systems such as Windows 9x systems. Here is my solution to the problem:



# for /f "tokens=3 delims=:" %i in ('arp -a ^| findstr /n /l ":" ^| find "2:"')
do @for /f %z in ('echo %i') do @set ip=%z


#echo %ip%
172.16.2.13


#