# Reboot Servers, Check Last Reboot and Email Report Anomaly

**URL:** <https://forum.ansible.com/t/reboot-servers-check-last-reboot-and-email-report-anomaly/44875>\
**Category:** Get Help\
**Tags:** ubuntu\
**Created:** [November 21, 2025, 5:25am UTC](https://forum.ansible.com/t/reboot-servers-check-last-reboot-and-email-report-anomaly/44875 "2025-11-21T05:25:43Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![twkl](https://avatars.discourse-cdn.com/v4/letter/t/9fc348/32.png) [@twkl](https://forum.ansible.com/u/twkl)\
**Post date:** [November 21, 2025, 5:25am UTC](https://forum.ansible.com/t/reboot-servers-check-last-reboot-and-email-report-anomaly/44875/1 "2025-11-21T05:25:43Z")

</div>

Hi,

I’ve got an ansible role with a task to reboot a bunch of servers, check last reboot and then email last reboot output:

```auto
# tasks file for reboot_status
- name: reboot
  ansible.builtin.reboot:
  become: true
  when: inventory_hostname != 'localhost'

- name: last reboot
  ansible.builtin.command: last reboot | head -1
  register: last_reboot_result

- name: email reboot_result
  community.general.mail:
    host: smtp.com.local
    port: 25
    from: Ansible Alert <ansible@com.local>
    to:
      - systemalerts@com.local
    subject: Reboot Status for Linux Servers
    body: "{{ lookup('template', 'templates/email_body.j2') }}"
    subtype: html
  run_once: true
  delegate_to: localhost

```

The email template looks like this:

```auto
<body>
    {% if 'wed4' in group_names %}
        <h3>Reboot Status for 4th Wednesday Collection</h3>
    {% elif 'wed3' in group_names %}
        <h3>Reboot Status for 3rd Wednesday Collection</h3>
    {% else %}
        <h3>Reboot Status for Ansible Server</h3>
    {% endif %}
    <p>Verify reboot status for the following servers:</p>
    <table>
        <thead>
            <tr>
                <th>Server</th>
                <th>Status</th>
            </tr>
        </thead>
        <tbody>
            {% if 'wed4' in group_names %}
            {% for host in groups['wed4'] %}
            <tr>
                <td>{{ host}}</td>
                <td>{{ last_reboot_result.stdout_lines[0] }}</td>
            </tr>
            {% endfor %}
            {% elif 'wed3' in group_names %}
            {% for host in groups['wed3'] %}
            <tr>
                <td>{{ host}}</td>
                <td>{{ last_reboot_result.stdout_lines[0] }}</td>
            </tr>
            {% endfor %}
            {% else %}
            <tr>
                <td>ansibleserver</td>
                <td>{{ last_reboot_result.stdout_lines[0] }}</td>
            </tr>
            {% endif %}
        </tbody>
    </table>
</body>

```

However, the Status column in the report is not accurate. I think its using the …

```auto
last_reboot_result.stdout_lines[0]

```

… from the first server its processing and repeating the result to all servers in the Status column.

The Status column looks like this:

```auto
reboot system boot 5.15.0-161-gener Wed Nov 19 18:00 still running

```

Which is wrong for some of the servers which are on a different kernel version. The logic in the role’s task isn’t quite right.

The cron job runs this command:

```auto
/usr/bin/ansible-playbook /etc/ansible/playbooks/playbook_reboot_status.yml --limit wed3

```

Any advice would be most appreciated.

Thanks.

---

<div class="post-metadata">

**Author:** ![twkl](https://avatars.discourse-cdn.com/v4/letter/t/9fc348/32.png) [@twkl](https://forum.ansible.com/u/twkl)\
**Post date:** [November 21, 2025, 6:13am UTC](https://forum.ansible.com/t/reboot-servers-check-last-reboot-and-email-report-anomaly/44875/2 "2025-11-21T06:13:39Z")

</div>

Think I figured it out. At least in terms of the solution by replacing the email body’s code to:

```auto
<tbody>
	{% for host in ansible_play_hosts_all %}
	<tr>
		<td>{{ host }}</td>
		<td>{{ hostvars[host].last_reboot_result.stdout_lines[0] }}</td>
	</tr>
	{% endfor %}
</tbody>

```

Previous convoluted code was probably just rehashing the variable “last\_reboot\_result.stdout\_lines[0]” from just one host.

Cheers.

---

<div class="post-metadata">

**Author:** ![rolandm](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/rolandm/32/755_2.png) [@rolandm](https://forum.ansible.com/u/rolandm)\
**Post date:** [November 21, 2025, 5:49pm UTC](https://forum.ansible.com/t/reboot-servers-check-last-reboot-and-email-report-anomaly/44875/3 "2025-11-21T17:49:51Z")

</div>

I am just wondering whether ansible.buibuin.command works with a shell command line:

last reboot | head -1

Shouldnt command take only a single host command and its parameters? Not even glob expressions for file pathes are supported neither any redirects nor piping.

For such cases module shell should be used

Br  
Roland

---

<div class="post-metadata">

**Author:** ![markstos](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/markstos/32/9706_2.png) [@markstos](https://forum.ansible.com/u/markstos)\
**Post date:** [November 24, 2025, 7:34pm UTC](https://forum.ansible.com/t/reboot-servers-check-last-reboot-and-email-report-anomaly/44875/4 "2025-11-24T19:34:06Z")

</div>

> [@rolandm](#):
>
> Shouldnt command take only a single host command and its parameters?

Yes, `command` takes a command and arguments to that command. In this case, it works by accident due to a quirk in how `last` is implemented. Something @felixfontein and @sivel helped me to figure out.

The `last` command takes a list of usernames as well as some arguments. It happens to accept `-1` as an argument that works just `head -1` would have. This is documented in `man last` under `-number`.

So the ‘|’ character is seen as a username, as is the `head` command while the `-1` arg limits the output. As it happens, the pipe and `head` args get ignored because no users logged in with that name while the `-1` arg does limit the output. It can be tested like this:

```auto
last reboot -1

```

So the `command` model can safely an clearly be used here to display only the most recent reboot with an alternate syntax.

---

<div class="post-metadata">

**Author:** ![twkl](https://avatars.discourse-cdn.com/v4/letter/t/9fc348/32.png) [@twkl](https://forum.ansible.com/u/twkl)\
**Post date:** [November 25, 2025, 9:02am UTC](https://forum.ansible.com/t/reboot-servers-check-last-reboot-and-email-report-anomaly/44875/5 "2025-11-25T09:02:29Z")

</div>

Thanks for the heads up. I’ll re-look at my playbook and switch to the shell module.

---

<div class="post-metadata">

**Author:** ![rolandm](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/rolandm/32/755_2.png) [@rolandm](https://forum.ansible.com/u/rolandm)\
**Post date:** [November 26, 2025, 7:24am UTC](https://forum.ansible.com/t/reboot-servers-check-last-reboot-and-email-report-anomaly/44875/6 "2025-11-26T07:24:53Z")

</div>

As alternative to use shell you can set also use “-n 1” with ‘last’. I tried this only now in my Linux box after until now only posting from an Android phone.

```
- name: last reboot
  #1#ansible.builtin.command: last reboot | head -1
  #2#
  ansible.builtin.command: last reboot -n 1
  register: last_reboot_result_raw
- debug: msg="{{ last_reboot_result_raw.stdout_lines }}"

```

Both variants of using ‘last’ have a three line output.

> ok: [localhost] =\> {  
> “msg”: [  
> “reboot system boot 5.15.0-161-gener Wed Nov 26 07:45 still running”,  
> “”,  
> “wtmp begins Wed Aug 14 08:31:33 2024”  
> ]  
> }

Then you can also set a fact and use variable last\_boot\_result in the template without need to fetch several times the first line.

```
- set_fact: last_reboot_result="{{ last_reboot_result_raw.stdout_lines[0] }}"

```

---

<div class="post-metadata">

**Author:** ![markstos](https://sea1.discourse-cdn.com/ansible/user_avatar/forum.ansible.com/markstos/32/9706_2.png) [@markstos](https://forum.ansible.com/u/markstos)\
**Post date:** [November 26, 2025, 1:36pm UTC](https://forum.ansible.com/t/reboot-servers-check-last-reboot-and-email-report-anomaly/44875/7 "2025-11-26T13:36:02Z")

</div>

You are right. I missed this the first time I searched `man last` because it’s not under -1 in the docs, it’s under `-number`. I’ve updated my answer to reflect that. Thanks!
