GCP / Guide 1
Getting started
The gcloud CLI from PowerShell, sign-in and configurations, working across projects, and Cloud Asset Inventory.
Everything in these Google Cloud notes can be done in the console, but repeatable work belongs in scripts. This guide sets up the Google Cloud CLI (gcloud), shows how to drive it from PowerShell, explains how sign-in, projects and regions work, and introduces Cloud Asset Inventory, which answers "what do we have?" across the whole organisation in one call.
About the example names
All examples use one test environment. Replace the names with your own. The full list is on the example environment page.
| Item | Example |
|---|---|
| Organization | ravindran.in (ID 123456789012) |
| Project | prj-notes-test |
| Region and zone | us-east1, us-east1-b |
| VPC network | vpc-notes-test (subnet 10.30.1.0/24) |
| VM instance | vm-notes-test-01 |
| Service account | sa-app@prj-notes-test.iam.gserviceaccount.com |
| Domain (Cloud DNS zone) | gcp.ravindran.in |
Tip 1 – Pick your tool
| Tool | Best for |
|---|---|
| gcloud CLI | Almost everything: every Google Cloud service, JSON output, the same commands on Windows, macOS and Linux. The scripts on this site call it from PowerShell. |
| Cloud Shell | gcloud in the browser, already signed in, with a small persistent home directory. Nothing to install. PowerShell is available too (pwsh). |
gcloud storage and bq | Cloud Storage and BigQuery. gcloud storage replaces the older gsutil. |
| Terraform / Infrastructure Manager | Creating infrastructure repeatably. Scripts report and fix; templates build. |
Google's own PowerShell module, Cloud Tools for PowerShell, is deprecated: since 14 January 2026 it can no longer be installed through the Google Cloud CLI, and its repository was archived in July 2026. Don't build new scripts on it. Calling gcloud with JSON output and converting it with ConvertFrom-Json works everywhere and uses the tool Google supports.
Tip 2 – Install the CLI and sign in
Install the Google Cloud CLI from Google's installer (Windows) or package repository (Linux, macOS), then:
# One-time: sign in, pick a default project, region and zone
gcloud init
# Separate credentials for scripts and client libraries (Application Default Credentials)
gcloud auth application-default login
# Who am I, and which project am I pointed at?
gcloud auth list
gcloud config list
gcloud auth login signs in the CLI itself; application-default login signs in code that uses Google's client libraries and Terraform. They're separate, which surprises most people the first time.
Use named configurations to switch between organisations or environments without re-typing flags:
gcloud config configurations create notes-test
gcloud config set project prj-notes-test
gcloud config set compute/region us-east1
gcloud config set compute/zone us-east1-b
gcloud config configurations activate notes-test
Tip 3 – Use JSON output in PowerShell
Every gcloud list and describe command can return JSON. Convert it to objects and PowerShell does the rest: filtering, grouping, CSV export.
# VMs in a project, as PowerShell objects
$vms = gcloud compute instances list --project prj-notes-test --format=json | ConvertFrom-Json
$vms | Select-Object name, status, @{n='Zone';e={ ($_.zone -split '/')[-1] }},
@{n='Type';e={ ($_.machineType -split '/')[-1] }} | Format-Table
# Let gcloud filter on the server side where it can: faster, and less to download
gcloud compute instances list --filter="status=RUNNING AND labels.environment=test" --format=json | ConvertFrom-Json
Two habits that save time: resource fields such as zone and machineType come back as full URLs, so split on / and take the last part; and check $LASTEXITCODE after each call, because gcloud errors don't stop a PowerShell script on their own.
Tip 4 – Loop over projects
In Google Cloud the project is the unit you work in: most commands act on one project at a time. Loop over the active ones:
$projects = gcloud projects list --filter="lifecycleState:ACTIVE" --format=json | ConvertFrom-Json
foreach ($p in $projects) {
$vms = @(gcloud compute instances list --project $p.projectId --format=json 2>$null | ConvertFrom-Json)
if ($LASTEXITCODE -ne 0) { Write-Warning "$($p.projectId): Compute Engine API not enabled or no access"; continue }
'{0}: {1} VM(s)' -f $p.projectId, $vms.Count
}
Unlike AWS, you don't need to loop over regions: gcloud compute instances list returns every zone in the project unless you filter.
Tip 5 – Search everything with Cloud Asset Inventory
Looping over projects works, but Cloud Asset Inventory searches every resource and IAM policy in a project, folder or the whole organisation in one call. It's the Google Cloud equivalent of Azure Resource Graph, and several scripts on this site use it.
# Every VM in the organisation, with its project, location and labels
gcloud asset search-all-resources --scope=organizations/123456789012 `
--asset-types=compute.googleapis.com/Instance --format=json | ConvertFrom-Json |
Select-Object displayName, project, location, state
# Everything without an owner label
gcloud asset search-all-resources --scope=organizations/123456789012 --query="NOT labels:owner" --format=json
# Who has Owner anywhere in the organisation
gcloud asset search-all-iam-policies --scope=organizations/123456789012 --query="policy:roles/owner" --format=json
It needs the Cloud Asset API enabled in the project you run from, and the roles/cloudasset.viewer role at the scope you search.
Tip 6 – Use service accounts for automation
Scheduled scripts shouldn't run as you, and they shouldn't use a downloaded service account key either (new organisations block key creation by default, and they're right to). Instead:
- On Google Cloud (a VM, Cloud Run job, Cloud Build): attach a service account to the resource. gcloud and the client libraries pick up its credentials automatically.
- Outside Google Cloud (GitHub Actions, Azure DevOps, AWS, on-premises): Workload Identity Federation exchanges the platform's own token for short-lived Google credentials. No key file.
- From your own machine, as a service account: impersonate it, which needs
roles/iam.serviceAccountTokenCreatoron that account and leaves an audit trail with your name on it:
gcloud compute instances list --impersonate-service-account=sa-reports@prj-notes-test.iam.gserviceaccount.com
Tip 7 – Keep a transcript, and use -WhatIf
Start-Transcript -Path ".\gcp-$(Get-Date -Format yyyyMMdd-HHmm).log"
.\Invoke-GcpVMPowerSchedule.ps1 -Action Stop -WhatIf # see what it would do
Stop-Transcript
Every script on this site that changes something supports -WhatIf. Reports are read-only and need only viewer roles: roles/viewer (or roles/browser plus the specific viewer roles) on the projects, and roles/cloudasset.viewer for the Asset Inventory scripts.