You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Ansible获取C盘剩余空间?win_disk_facts模块使用疑问

Hey there! Let's break down your two Ansible issues one by one— I've run into similar Windows disk fact headaches before, so I know exactly where you might be getting stuck.


Problem 1: selectattr("drive_letter", "C") returns empty results

The issue here has two key reasons:

  1. Wrong attribute nesting: The drive_letter field isn't directly on the top-level disk object—it lives inside the nested partitions → volumes structure under each disk. Your current filter is trying to filter disks by a property they don't even have.
  2. Incorrect drive letter format: win_disk_facts returns drive letters with a colon (e.g., C:) instead of just C. Even if you were filtering the right level, matching against "C" would never find a match.

Fixes to grab the C drive without hardcoding indexes

You have two clean, reliable options:

Option 1: Use json_query (best for nested structures)

json_query is built for digging into complex nested data. This one-liner directly pulls the C: volume details:

- name: Fetch C drive details with json_query
  set_fact:
    c_drive: "{{ ansible_facts.disks | json_query('[].partitions[].volumes[] | [?drive_letter == `C:`] | [0]') }}"

You can then access the remaining space with {{ c_drive.size_remaining }}.

Option 2: Use nested Jinja filters

If you prefer sticking to core Jinja tools, flatten the nested lists first, then filter:

- name: Set C drive variable with Jinja filters
  set_fact:
    c_drive: "{{ ansible_facts.disks | sum(attribute='partitions', start=[]) | sum(attribute='volumes', start=[]) | selectattr('drive_letter', 'equalto', 'C:') | first }}"
  • sum(attribute='partitions', start=[]) flattens all partitions from all disks into a single list
  • The second sum flattens all volumes from those partitions
  • selectattr picks the volume with drive letter C:
  • first grabs the only (in most cases) matching volume

Problem 2: Variable diskC is undefined after assignment

If directly printing the hardcoded index path works but storing it in diskC doesn't, here are the most likely fixes:

1. Fix syntax errors in set_fact

Double-check your task for missing quotes or YAML formatting issues. For example:

# Correct syntax
- name: Define diskC variable
  set_fact:
    diskC: "{{ ansible_facts.disks[0].partitions[1].volumes[0].size_remaining }}"

# Wrong (missing quotes around the Jinja expression)
- name: Define diskC variable
  set_fact:
    diskC: ansible_facts.disks[0].partitions[1].volumes[0].size_remaining

2. Ensure variable assignment runs in the right context

If your set_fact task is inside a when clause that doesn't evaluate to true, or if it's in a separate play without fact persistence, diskC won't be defined. Make sure the set_fact runs immediately after win_disk_facts in the same play.

3. Add safety checks for filter-based assignments

If you tried assigning diskC using your original broken filter, the result would be an empty list. Using | first on an empty list throws a Jinja error, which stops set_fact from completing—so diskC never gets created. Add a safety net:

- name: Set diskC safely
  set_fact:
    diskC: "{{ (ansible_facts.disks | sum(attribute='partitions', start=[]) | sum(attribute='volumes', start=[]) | selectattr('drive_letter', 'equalto', 'C:') | list) | first | default(None) }}"

default(None) ensures diskC gets set to None instead of failing if no C: drive is found.


Once you have your C drive variable defined, checking for less than 4GB is straightforward:

- name: Warn if C drive has insufficient space
  debug:
    msg: "C drive has less than 4GB remaining ({{ c_drive.size_remaining | human_readable }})"
  when: c_drive.size_remaining < 4*1024*1024*1024  # Convert 4GB to bytes

内容的提问来源于stack exchange,提问作者Junn Sorran

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:07:58