text: #!/usr/bin/python
  
  #
  # Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
  #
  # Permission is hereby granted, free of charge, to any person obtaining a copy of this
  # software and associated documentation files (the "Software"), to deal in the Software
  # without restriction, including without limitation the rights to use, copy, modify,
  # merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
  # permit persons to whom the Software is furnished to do so.
  #
  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
  # INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  # PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
  # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
  # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  #
  
  import boto3
  import os
  import logging
  import time
  import json
  from botocore.exceptions import ClientError,EndpointConnectionError
  
  RegistrationCodes = {}
  Logger            = None
  DDBTableName      = "WorkspacesPortal"
  
  def GetRegCode(Client, DirectoryId):
      global Logger
      
      if DirectoryId in RegistrationCodes: return(RegistrationCodes[DirectoryId])
      
      try:
          DirectoryList = Client.describe_workspace_directories()
      except Exception as e:
          Logger.error("Did not get list of directories: "+str(e))
          return("")
          
      for Dir in DirectoryList["Directories"]:
          RegistrationCodes[Dir["DirectoryId"]] = Dir["RegistrationCode"]
  
      if DirectoryId in RegistrationCodes: return(RegistrationCodes[DirectoryId])
  
      return("")
          
  def lambda_handler(event, context):
      global Logger,DDBTableName
      
      logging.basicConfig()
      logging.getLogger('boto3').setLevel(logging.CRITICAL)
      logging.getLogger('botocore').setLevel(logging.CRITICAL)
      logging.getLogger('s3transfer').setLevel(logging.CRITICAL)
      logging.getLogger('urllib3').setLevel(logging.CRITICAL)
      Logger = logging.getLogger()
      level = logging.getLevelName(os.environ.get("LOGLEVEL",'INFO'))
      Logger.setLevel(level)
  
      if os.environ.get("DynamoDBTableName") is not None: DDBTableName = os.environ.get("DynamoDBTableName")
  
      Regions = []
      if os.environ.get("REGIONLIST") is not None:
          Regions = os.environ.get("REGIONLIST").split(",")
          Logger.info("Regions: "+",".join(Regions))
      else:
          try:
              EC2 = boto3.client("ec2")
              Response = EC2.describe_regions()
              for Region in Response["Regions"]:
                  Regions.append(Region["RegionName"])
          except Exception as e:
              Logger.error("Unable to get a list of regions: "+str(e))
              Regions.append("us-east-1")
          Logger.info("All regions: "+"".join(Regions))
  
      for TargetRegion in Regions:
          Logger.info("Checking: "+TargetRegion)
          WorkspacesClient = boto3.client("workspaces", region_name=TargetRegion)
          paginator = WorkspacesClient.get_paginator("describe_workspaces")
       
          try:
              ListResponse = {}
              for page in paginator.paginate(PaginationConfig={"PageSize": 25}):
                  if ListResponse:
                      ListResponse["Workspaces"] = (
                          ListResponse["Workspaces"] + page["Workspaces"]
                      )
                  else:
                      ListResponse = {**ListResponse, **page}
              logging.debug(
                  "ListResponse  %s, size %s",
                  ListResponse["Workspaces"],
                  len(ListResponse["Workspaces"]),
              )
              logging.info("Found %s workspaces", len(ListResponse["Workspaces"]))
          except EndpointConnectionError as e:
              Logger.warning("Could not connect to endpoint in region "+TargetRegion)
              continue
          except Exception as e:
              Logger.error("Failed to get Workspaces list for region "+TargetRegion+" - "+str(e))
              continue
              
          if len(ListResponse["Workspaces"]) == 0:
              Logger.info("  No Workspaces instances found in region "+TargetRegion)
              continue
  
          #
          # Here we get the connection details for all the Workspaces instances at once
          # It is more efficient this way even though we could call this API
          # individually for each instance we have in ListResponse
          #
          Results = WorkspacesClient.describe_workspaces_connection_status()
          ConnectionResponse = Results
          while Results.get("NextToken"):
              Results = WorkspacesClient.describe_workspaces_connection_status(
                  NextToken=Results["NextToken"]
              )
              ConnectionResponse["WorkspacesConnectionStatus"] = (
                  ConnectionResponse["WorkspacesConnectionStatus"]
                  + Results["WorkspacesConnectionStatus"]
              )
          logging.info(
              "Found %s workspaces_connection_status",
              len(ConnectionResponse["WorkspacesConnectionStatus"]),
          )
          LastConnectedTime = {}
          for Connection in ConnectionResponse["WorkspacesConnectionStatus"]:
              try:
                  LastConnectedTime[Connection["WorkspaceId"]] = Connection["LastKnownUserConnectionTimestamp"].strftime("%s")
              except:
                  pass
  
          DynamoDBClient = boto3.client("dynamodb")
          for Instance in ListResponse["Workspaces"]:
              Logger.info("  WorkspaceId: "+Instance["WorkspaceId"])
  
              Item = {"WorkspaceId":  {"S":Instance["WorkspaceId"]},
                      "UserName":     {"S":Instance["UserName"]},
                      "Region":       {"S":TargetRegion},
                      "InstanceState":{"S":Instance["State"]},
                      "LastTouched":  {"N":str(time.time())},
                      "RunningMode":  {"S":Instance["WorkspaceProperties"]["RunningMode"]},
                      "RegCode":      {"S":GetRegCode(WorkspacesClient, Instance["DirectoryId"])}
              }
  
              if "ComputerName"          in Instance:          Item["ComputerName"]  = {"S":Instance["ComputerName"]}
              if "IpAddress"             in Instance:          Item["IPAddress"]     = {"S":Instance["IpAddress"]}
              if Instance["WorkspaceId"] in LastConnectedTime: Item["LastConnected"] = {"N":LastConnectedTime[Instance["WorkspaceId"]]}
              Logger.debug(
                  "  WorkspaceId: " + Instance["WorkspaceId"] + " " + json.dumps(Item)
              )
              try:
                  DynamoDBClient.put_item(TableName=DDBTableName, Item=Item)
              except ClientError as e:
                  Logger.error("DynamoDB error: "+e.response["Error"]["Message"])
  