Azure自动化账户Python3.8:排查空存储账户脚本遇迭代错误求助
问题描述
我在Azure自动化账户(Python 3.8环境)中编写Python SDK脚本,想要筛选出不包含Blob容器、表、队列、文件共享的存储账户,但运行时触发错误:
TypeError: 'ListContainerItems' object is not iterable
错误出现在代码行:containers = list(storage_client.blob_containers.list(resource_group_name, account_name))
原脚本如下:
from azure.common.credentials import ServicePrincipalCredentials from azure.mgmt.compute import ComputeManagementClient from azure.mgmt.storage import StorageManagementClient client_id = 'XXX' tenant_id = 'XXX' client_secret = 'XXX' subscription_id = ('subscription_id') credentials = ServicePrincipalCredentials(client_id, client_secret, tenant=tenant_id) from azure.mgmt.storage import StorageManagementClient storage_client = StorageManagementClient(credentials, subscription_id) # Get a list of all storage accounts in the subscription storage_accounts = storage_client.storage_accounts.list() # Loop through each storage account and check if it has containers, tables, queues, or file shares for account in storage_accounts: account_name = account.name resource_group_name = account.id.split("/")[4] # Check if the storage account has containers containers = list(storage_client.blob_containers.list(resource_group_name, account_name)) #print(containers) if containers: continue # Check if the storage account has tables tables = list(storage_client.table.list(resource_group_name, account_name)) if tables: continue # Check if the storage account has queues queues = list(storage_client.queue.list(resource_group_name, account_name)) if queues: continue # Check if the storage account has file shares file_shares = list(storage_client.file_shares.list(resource_group_name, account_name)) if file_shares: continue # If none of the above resources are found, print the storage account name as orphan print(f"Orphaned Storage account name {account_name}.")
错误原因
Azure Storage Management SDK的list()方法(比如blob_containers.list())返回的是ListContainerItems(或对应资源的ListXXItems)对象,这类对象本身不可直接迭代,需要访问其value属性才能获取实际的资源列表。直接用list()包裹会触发迭代错误。
另外补充:ServicePrincipalCredentials已被Azure SDK弃用,建议改用azure.identity.ClientSecretCredential,但自动化账户中若需兼容旧版本可暂时保留。
解决方案
将所有list(storage_client.XX.list(...))的写法替换为storage_client.XX.list(...).value,通过value属性获取可迭代的资源列表。同时优化资源组名称的提取逻辑,避免split索引越界。
修正后的脚本
from azure.common.credentials import ServicePrincipalCredentials from azure.mgmt.storage import StorageManagementClient # 配置身份信息 client_id = 'XXX' tenant_id = 'XXX' client_secret = 'XXX' subscription_id = 'subscription_id' # 初始化认证和客户端 credentials = ServicePrincipalCredentials(client_id, client_secret, tenant=tenant_id) storage_client = StorageManagementClient(credentials, subscription_id) # 获取订阅下所有存储账户 storage_accounts = storage_client.storage_accounts.list() # 遍历存储账户检查资源 for account in storage_accounts: account_name = account.name # 更稳妥的资源组名称提取方式 resource_group_name = account.id.split("/")[account.id.split("/").index("resourceGroups") + 1] # 检查Blob容器 containers = storage_client.blob_containers.list(resource_group_name, account_name).value if containers: continue # 检查表 tables = storage_client.table.list(resource_group_name, account_name).value if tables: continue # 检查队列 queues = storage_client.queue.list(resource_group_name, account_name).value if queues: continue # 检查文件共享 file_shares = storage_client.file_shares.list(resource_group_name, account_name).value if file_shares: continue # 输出无资源的存储账户 print(f"无关联资源的存储账户:{account_name}")
补充说明
- 若使用新版Azure SDK,建议替换认证方式为
ClientSecretCredential,示例代码如下:
from azure.identity import ClientSecretCredential credentials = ClientSecretCredential( tenant_id=tenant_id, client_id=client_id, client_secret=client_secret )
- 运行脚本前需确保自动化账户的服务主体拥有足够的权限(如Storage Account Contributor或Reader权限),否则会出现权限不足的错误。
内容的提问来源于stack exchange,提问作者DSH
相关产品推荐
相关产品推荐

