[
  {
    "path": "ACE-Docker/README.md",
    "content": "# ACE-Docker\nThis project focuses on simplifying ACE's deployment process as much as possible.\n\n## Goals\n\n## Components\n\n### [specterops/ace-mssql-linux](https://hub.docker.com/r/specterops/ace-mssql-linux/)\nMSSQL Server. This database provides a backend to keep track of all of the data ACE needs to do its job. This includes User, Credential, Computer, Script, and Schedules.\n\n### [specterops/ace-rabbitmq](https://hub.docker.com/r/specterops/ace-rabbitmq/)\nRabbitMQ Messaging System. ACE's enrichment pipeline is built on a robust messaging system that guides each scan result through data enrichments, like Virus Total hash lookups, all the way to ingestion into a SIEM.\n\n### [specterops/ace-nginx](https://hub.docker.com/r/specterops/ace-nginx/)\nNGINX HTTP(S) Reverse Proxy. Proxy's access to the ACE Web Application and provides SSL Certificates for those connections.\n\n## Getting Started\nOur goal is to make provisioning ACE as simple as possible, so we wrote a small batch script to get things set up. Follow the steps, on a Linux or OSX machine, below and you should be in business:\n* Install Docker\n* If on Linux, Install Docker Compose\n* Adjust Docker preferences to allow containers to use 4GBs of RAM (Docker -> Preferences -> Advanced -> Memory)\n* Download this repository\n* Execute start.sh\n\nstart.sh is a simple shell script that accomplishes the remaining set up steps. Below is a list of tasks accomplished by start.sh:\n* Create SSL certificate\n* Add SSL Thumbprint to the ACE Web Application's appsettings.json file\n* Build ACE Docker images with Docker Compose\n* Start ACE Docker containers"
  },
  {
    "path": "ACE-Docker/ace-ca/dockerfile",
    "content": "FROM cfssl/cfssl:latest\n\nRUN cfssl print-defaults config > ca-config.json && cfssl print-defaults csr > ca-csr.json \\  \n&& cfssl genkey -initca ca-csr.json | cfssljson -bare ca\n\nEXPOSE 8888\n\nENTRYPOINT [\"cfssl\"]\n\nCMD [\"serve\",\"-ca=ca.pem\",\"-ca-key=ca-key.pem\",\"-address=0.0.0.0\"]"
  },
  {
    "path": "ACE-Docker/ace-nginx/Dockerfile",
    "content": "FROM nginx\nMAINTAINER Jared Atkinson <jared@invoke-ir.com>\nRUN apt-get update; apt-get install -y openssl\nCOPY ./nginx.conf /etc/nginx/nginx.conf\nCOPY ./entrypoint.sh /opt/entrypoint.sh\nRUN chmod +x /opt/entrypoint.sh\nCMD /bin/bash /opt/entrypoint.sh && nginx -c /etc/nginx/nginx.conf -g \"daemon off;\""
  },
  {
    "path": "ACE-Docker/ace-nginx/README.md",
    "content": "Built on [nginx](https://hub.docker.com/_/nginx/), this image provides an SSL proxy for the [ACE Web Application](https://github.com/Invoke-IR/ACE/tree/master/ACE-WebService). \n\nACE relies on SSL for two important features: \n* Encryption - Data sent to and from the ACE Web Application is encrypted\n* Authentication - Certificate pinning is used to provide server side authentication to avoid Man-in-the-Middle attacks.\n\n## Using this Image\nThe ACE Nginx can be run in a couple different ways. \n### Standalone\nIf you are running ACE in a test/development/standalone deployment, then you can simply run the container as shown below.\n```\ndocker run --name ace-nginx -p 80:80 -p 443:443 -d specterops/ace-nginx\n```\n### Clustered/Redundant\nIf you plan on running ACE in a Kubernetes cluster with replication, you want to maintain the same SSL certificates in all instances of the specterops/ace-nginx image. This can be achieved through the use of Volumes. \n\nSimply create a docker volume (it can be named \"certs\" or whatever you choose).\n```\ndocker volume create --name certs\n```\n\nThen run your container(s) with the -v flag, linking your newly created volume to \"/etc/nginx/certs\". The volume will ensure a consistent SSL certificate across all ace-nginx instances.\n```\ndocker run --name ace-nginx -v certs:/etc/nginx/certs -p 80:80 -p 443:443 -d specterops/ace-nginx\n```\n\n### Get SSL Certificate Thumbprint\nThe .NET WebClient does not trust self-signed SSL Certificates by default. The ACE PowerShell module bypasses this limitation by using certificate pinning, where the PowerShell script compares the user supplied SSL Thumbprint to that returned by the target server. If the Thumbprints match, then the server is authenticated and the request is allowed. The SSL Thumbprint is output at container runtime and can be found with the following command:\n```\ndocker logs ace-nginx\n################################################################\n# ACE SSL Thumbprint: 3179CC1A0A0E20477260BFB8D559F35240297E6B #\n################################################################\n```"
  },
  {
    "path": "ACE-Docker/ace-nginx/entrypoint.sh",
    "content": "#!/bin/sh\n\n# Add Environment Variable to nginx.conf\nsed -i -e 's/\\[WEBSERVICE_IP\\]/'\"$WEBSERVICE_IP\"'/g' /etc/nginx/nginx.conf\n\n# Check if /etc/nginx/certs directory exits\nif [ ! -d /etc/nginx/certs ]; then\n    mkdir /etc/nginx/certs\nfi\n\n# Check if SSL Cert exists, if it doesn't then make it\nif [ ! -f /etc/nginx/certs/server.crt ]; then\n    openssl req -x509 -nodes -days 365 -newkey rsa:2048 -subj \"/C=US/ST=Washington/L=Seattle/O=web.ace/CN=local.specterops.ace\" -keyout \"/etc/nginx/certs/server.key\" -out \"/etc/nginx/certs/server.crt\" 2> /dev/null\nfi\n\n# Get and output SSL Thumbprint\nfingerprint=$(openssl x509 -in /etc/nginx/certs/server.crt -noout -fingerprint | sed 's/SHA1 Fingerprint=//g' |  sed 's/://g')\necho \"\\\"Thumbprint\\\": \\\"$fingerprint\\\",\""
  },
  {
    "path": "ACE-Docker/ace-nginx/nginx.conf",
    "content": "worker_processes 4;\n\nevents { worker_connections 1024; }\n\nhttp {\n    # Allow files of <= 2MB to be uploaded\n    client_max_body_size 2M;\n\n    # Act as Load Balancer for 4 nodes\n    upstream web.ace.local {\n        server [WEBSERVICE_IP]:80;\n#        server dockernginxkestrel_core-app_2:80;\n#        server dockernginxkestrel_core-app_3:80;\n#        server dockernginxkestrel_core-app_4:80;\n    }\n\n    # Redirect all HTTP traffic to HTTPS\n    server {\n      listen 80;\n      return 301 https://$host$request_uri;\n    }\n    \n    # HTTPS Server\n    server {\n        # Listen on port 443\n        listen 443;\n\n        # Server name. You need a DNS record (or add this hostname to your hosts file)\n        server_name web.ace.local;\n\n        # Digital certificates generated with makecert.sh / makecert.bat\n        ssl_certificate     /etc/nginx/certs/server.crt;\n        ssl_certificate_key /etc/nginx/certs/server.key;\n\n        # SSL configuration\n        ssl on;\n        ssl_session_cache  builtin:1000  shared:SSL:10m;\n        ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;\n        ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;\n        ssl_prefer_server_ciphers on;\n\n        # Location configuration to use the core-app.local upstream defined before\n        location / {\n            proxy_pass          http://web.ace.local;\n            proxy_read_timeout  90;\n            proxy_set_header        Host $host;\n            proxy_set_header        X-Real-IP $remote_addr;\n            proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;\n            proxy_set_header        X-Forwarded-Proto $scheme;       \n\n            proxy_redirect      http://localhost https://web.ace.local;\n        }\n    }\n}"
  },
  {
    "path": "ACE-Docker/ace-rabbitmq/Dockerfile",
    "content": "FROM  rabbitmq:3-management\nMAINTAINER Jared Atkinson <jared@invoke-ir.com>\nADD ace-entrypoint.sh /root/ace-entrypoint.sh\nADD ace-cache.py /root/ace-cache.py\nADD ace-lookup.py /root/ace-lookup.py\nRUN \\\n    chmod +x /root/ace-entrypoint.sh \\\n    && chmod +x /root/ace-cache.py \\\n    && chmod +x /root/ace-lookup.py \\\n    && apt-get update -y \\\n    && apt-get upgrade -y \\\n    && apt-get dist-upgrade -y \\\n    && apt-get install -y python2.7 python-pip \\\n    && pip install pika requests\nCMD \\\n    /usr/local/bin/docker-entrypoint.sh rabbitmq-server > /dev/null & \\\n    sleep 30 \\\n    && /root/ace-entrypoint.sh"
  },
  {
    "path": "ACE-Docker/ace-rabbitmq/README.md",
    "content": "Built on [RabbitMQ](https://hub.docker.com/_/rabbitmq/), this images provides the backend database used by the [ACE RabbitMQ Server](https://github.com/Invoke-IR/ACE/tree/master/ACE-RabbitMQ).\n\n## Requirements\n* This image requires Docker Engine 1.8+ in any of their supported platforms.\n* Requires the following environment flags\n* RABBITMQ_DEFAULT_USER=<username>\n* RABBITMQ_DEFAULT_PASS=<your_strong_password>\n* APIKEY=<virustotal_apikey>\n\n## Using this Image\n### Run\n```\ndocker run --name ace-rabbitmq -e 'RABBITMQ_DEFAULT_USER=yourUsername' -e 'RABBITMQ_DEFAULT_PASS=yourPassword' -e 'APIKEY=yourVirusTotalPublicAPIKey' -p 5672:5672 -p 15672:15672 -d specterops/ace-rabbitmq\n```\n# For Persistence\nIf you desire your RabbitMQ data and setting to persist between containers, you need to create a docker volume `docker volume create rabbitmq` then add `-v rabbitmq:/var/lib/rabbitmq` to the docker run command\n\n### Environment Variables\n* **RABBITMQ_DEFAULT_USER** Username for RabbitMQ server. Will be used to connect to server and log into management interface.\n* **RABBITMQ_DEFAULT_PASS** Password for RabbitMQ server. Will be used to connect to server and log into management interface.\n* **APIKEY** Public VirusTotal API key. Allows for lookups of hashes on VirusTotal"
  },
  {
    "path": "ACE-Docker/ace-rabbitmq/ace-cache.py",
    "content": "#!/usr/bin/env python\nimport json\nimport sys\nimport pika\nimport requests\nfrom argparse import ArgumentParser\nfrom json import dumps\n\n# Our local cache of hashes. Each of the consumers checks this dictionary first\n# before doing a lookup against VirusTotal to save time and API queries\ncachedEntries = {}\n\nclass CachedConsumer(object):\n    \"\"\"A consumer that receives hashes and queries the VirusTotal api\n    to find if VirusTotal has any matching hashes, and how many positive\n    (malicious) results for that hash.\n    \"\"\"\n    EXCHANGE = 'ace_exchange'\n    EXCHANGE_TYPE = 'topic'\n\n    def __init__(self, connection):\n        \"\"\"Create a new instance of LookupConsumer, passing in the API key to use.\n\n        :param connection connection: A pika connection object.\n        \"\"\"\n        self._connection = connection\n        self._channel = None\n\n    def consume_message(self, channel, method, properties, body):\n        \"\"\"Consume a message from channel. This function is passed as a callback\n        to basic_consume. After checking the body of the message, the consumer checks the\n        cache and either publish the cached entry, or perform a lookup and add the result\n        to the cache.\n        \"\"\"\n        self._channel = channel\n        message = json.loads(body) # parse the JSON results from the message\n        newRoutingKey = \"\"\n        if 'SHA256Hash' in message and message['SHA256Hash'] is not None:\n            sha256hash = message['SHA256Hash'] # assign the value temporarily instead of doing a lookup each time\n            if sha256hash in cachedEntries: #hash is cached\n                print \"Hash is cached\"\n                message[u\"VTRecordExists\"] = cachedEntries[sha256hash][u\"VTRecordExists\"]\n                if u\"VTPositives\" in cachedEntries[sha256hash]:\n                    message[u\"VTPositives\"] = cachedEntries[sha256hash][u\"VTPositives\"]\n                enrichment,newRoutingKey = method.routing_key.split(\".\",1)\n                self.publish_message(method, message, newRoutingKey)\n            elif u'VTRecordExists' in message: #needs to be cached\n                print \"Adding hash to cache\"\n                cachedEntries[sha256hash] = {}\n                cachedEntries[sha256hash][u\"VTRecordExists\"] = message[u\"VTRecordExists\"]\n                if u'VTPositives' in message:\n                    cachedEntries[sha256hash][u'VTPositives'] = message[u'VTPositives']\n                enrichment,newRoutingKey = method.routing_key.split(\".\",1)\n                self.publish_message(method, message, newRoutingKey)\n            else: #send for lookup\n                print \"sending to VT\"\n                newRoutingKey = \"lookup.\" + method.routing_key\n                self.publish_message(method, message, newRoutingKey)\n                self._connection.sleep(1)\n        elif message['SHA256Hash'] is None:\n            print \"Hash is null\"\n            enrichment,newRoutingKey = method.routing_key.split(\".\",1)\n            self.publish_message(method, message, newRoutingKey)\n\n    def publish_message(self, method, message, routingKey):\n        \"\"\"Publish a message to the channel with the new routing key after enrichment.\n        \"\"\"\n        body = json.dumps(message)\n        channel = self._channel\n        channel.basic_ack(delivery_tag = method.delivery_tag)\n        channel.basic_publish(exchange=self.EXCHANGE, routing_key=routingKey,body=body, properties=pika.BasicProperties(delivery_mode = 2,))\n\ndef main():\n    parser = ArgumentParser()\n    parser.add_argument(\n        '-s', '--Server', dest='rabbitmq_server', default='',\n        help='[MANDATORY] RabbitMQ server hostname or IP address')\n    parser.add_argument(\n        '-u', '--User', dest='rabbitmq_user', default='',\n        help='[OPTIONAL] RabbitMQ username')\n    parser.add_argument(\n        '-p', '--Password', dest='rabbitmq_password', default='',\n        help='[OPTIONAL] RabbitMQ password')\n\n    args = parser.parse_args()\n    try:\n        if (args.rabbitmq_password != '' and args.rabbitmq_user != ''):\n            creds = pika.PlainCredentials(args.rabbitmq_user, args.rabbitmq_password)\n            connection = pika.BlockingConnection(pika.ConnectionParameters(host=args.rabbitmq_server,\n                                            credentials=creds))\n        elif (args.rabbitmq_server != ''):\n            connection = pika.BlockingConnection(pika.ConnectionParameters(host=args.rabbitmq_server))\n        else:\n            print(\"Must provide command line parameters, run 'python ACE_RabbitMQ.py -h' for help\")\n            return\n        channel = connection.channel()\n    except:\n        print(\"Issue connecting to RabbitMQ,\")\n\n    channel.exchange_declare(exchange='ace_exchange',exchange_type='topic', durable=True)\n\n    channel.queue_declare(queue='siem', durable=True)\n    channel.queue_declare(queue='cached_hash', durable=True)\n    channel.queue_declare(queue='lookup', durable=True)\n    channel.queue_declare(queue='status', durable=True)\n\n    channel.queue_bind(exchange='ace_exchange', queue='siem', routing_key='siem')\n    channel.queue_bind(exchange='ace_exchange', queue='cached_hash', routing_key='hash.#')\n    channel.queue_bind(exchange='ace_exchange', queue='lookup', routing_key='lookup.hash.#')\n    channel.queue_bind(exchange='ace_exchange', queue='status', routing_key='status')\n    channel.basic_qos(prefetch_count=1)\n\n\n    print(\"Waiting for messages\")\n\n    cacheConsume = CachedConsumer(connection)\n\n    channel.basic_consume(cacheConsume.consume_message, queue='cached_hash')\n\n    channel.start_consuming()\n    \n    connection.close()\n\nif __name__ == '__main__':\n    main()"
  },
  {
    "path": "ACE-Docker/ace-rabbitmq/ace-entrypoint.sh",
    "content": "#!/bin/bash\npython /root/ace-lookup.py -s 127.0.0.1 -u $RABBITMQ_DEFAULT_USER -p $RABBITMQ_DEFAULT_PASS -k $APIKEY &\npython /root/ace-cache.py -s 127.0.0.1 -u $RABBITMQ_DEFAULT_USER -p $RABBITMQ_DEFAULT_PASS &\n\necho \"\\\"RabbitMQUserName\\\": \\\"$RABBITMQ_DEFAULT_USER\\\",\"\necho \"\\\"RabbitMQPassword\\\": \\\"$RABBITMQ_DEFAULT_PASS\\\",\"\n\nwhile true; do :; sleep 600; done"
  },
  {
    "path": "ACE-Docker/ace-rabbitmq/ace-lookup.py",
    "content": "#!/usr/bin/env python\nimport json\nimport sys\nimport pika\nimport requests\nfrom argparse import ArgumentParser\nfrom json import dumps\n\nclass VTConsumer(object):\n    \"\"\"A consumer that receives hashes and queries the VirusTotal api\n    to find if VirusTotal has any matching hashes, and how many positive\n    (malicious) results for that hash.\n    \"\"\"\n    EXCHANGE = 'ace_exchange'\n    EXCHANGE_TYPE = 'topic'\n\n    def __init__(self, api_key, connection):\n        \"\"\"Create a new instance of VTConsumer, passing in the API key to use.\n\n        :param str api_key: The VirusTotal API key to use.\n        :param connection connection: A pika connection object.\n        \"\"\"\n        self._apikey = api_key\n        self._connection = connection\n        self._channel = None\n\n    def consume_message(self, channel, method, properties, body):\n        \"\"\"Consume a message from channel. This function is passed as a callback\n        to basic_consume. After checking the body of the message, the consumer checks the\n        cache and either publish the cached entry, or perform a lookup and add the result\n        to the cache.\n        \"\"\"\n        self._channel = channel\n        message = json.loads(body) # parse the JSON results from the message\n        entry = {}\n        sha256hash = message['SHA256Hash']\n        entry = self.lookup_hash(sha256hash)\n        print entry\n        if u'VTRecordExists' in entry:\n            message[u\"VTRecordExists\"] = entry[u\"VTRecordExists\"]\n        if u'VTPositives' in entry:\n            message[u'VTPositives'] = entry[u'VTPositives']\n        self.publish_message(method, message)\n\n    def lookup_hash(self, sha256hash):\n        \"\"\"Perform a lookup against VirusTotal for a given hash.\n\n        :param str vt_hash: A SHA256Hash to check against the VirusTotal API.\n        \"\"\"\n        params = { 'apikey': self._apikey, 'resource': sha256hash }\n        headers = {\"Accept-Encoding\": \"gzip, deflate\", \"User-Agent\" : \"gzip, VirusTotal ACE Enrichment Consumer v0.1\"}\n        response = requests.get('https://www.virustotal.com/vtapi/v2/file/report', params=params, headers=headers)\n        if response.status_code == 204:\n            self._connection.sleep(60)\n            response = requests.get('https://www.virustotal.com/vtapi/v2/file/report', params=params, headers=headers)\n        json_response = response.json()\n        if json_response['response_code'] == 1:\n            new_record = {}\n            new_record[u\"VTRecordExists\"] = u\"True\"\n            new_record[u\"VTPositives\"] = json_response['positives']\n        elif json_response['response_code'] == 0:\n            new_record = {}\n            new_record[u\"VTRecordExists\"] = u\"False\"\n        elif json_response['response_code'] == -2:\n            new_record = {}\n            new_record[u\"VTRecordExists\"] = u\"False\"\n        return new_record\n\n    def publish_message(self, method, message):\n        \"\"\"Publish a message to the channel with the new routing key after enrichment.\n        \"\"\"\n        enrichment,newRoutingKey = method.routing_key.split(\".\",1)\n        body = json.dumps(message)\n        channel = self._channel\n        channel.basic_ack(delivery_tag = method.delivery_tag)\n        channel.basic_publish(exchange=self.EXCHANGE, routing_key=newRoutingKey,body=body, properties=pika.BasicProperties(delivery_mode = 2,))\n\ndef main():\n    parser = ArgumentParser()\n    parser.add_argument(\n        '-s', '--Server', dest='rabbitmq_server', default='',\n        help='[MANDATORY] RabbitMQ server hostname or IP address')\n    parser.add_argument(\n        '-u', '--User', dest='rabbitmq_user', default='',\n        help='[OPTIONAL] RabbitMQ username')\n    parser.add_argument(\n        '-p', '--Password', dest='rabbitmq_password', default='',\n        help='[OPTIONAL] RabbitMQ password')\n    parser.add_argument(\n        '-k', '--APIKey', dest='VTAPIKey', default='',\n        help='[MANDATORY] VirusTotal API Key')\n\n    args = parser.parse_args()\n    try:\n        if (args.VTAPIKey == ''):\n            print(\"Must provide command line parameters, run 'python ACE_RabbitMQ.py -h' for help\")\n            return\n        if (args.rabbitmq_password != '' and args.rabbitmq_user != ''):\n            creds = pika.PlainCredentials(args.rabbitmq_user, args.rabbitmq_password)\n            connection = pika.BlockingConnection(pika.ConnectionParameters(host=args.rabbitmq_server,\n                                            credentials=creds))\n        elif (args.rabbitmq_server != ''):\n            connection = pika.BlockingConnection(pika.ConnectionParameters(host=args.rabbitmq_server))\n        else:\n            print(\"Must provide command line parameters, run 'python ACE_RabbitMQ.py -h' for help\")\n            return\n        channel = connection.channel()\n    except:\n        print(\"Issue connecting to RabbitMQ,\")\n\n    channel.exchange_declare(exchange='ace_exchange',exchange_type='topic', durable=True)\n\n    channel.queue_declare(queue='siem', durable=True)\n    channel.queue_declare(queue='cached_hash', durable=True)\n    channel.queue_declare(queue='lookup', durable=True)\n    channel.queue_declare(queue='status', durable=True)\n\n    channel.queue_bind(exchange='ace_exchange', queue='siem', routing_key='siem')\n    channel.queue_bind(exchange='ace_exchange', queue='cached_hash', routing_key='hash.#')\n    channel.queue_bind(exchange='ace_exchange', queue='lookup', routing_key='lookup.hash.#')\n    channel.queue_bind(exchange='ace_exchange', queue='status', routing_key='status')\n    channel.basic_qos(prefetch_count=1)\n\n\n    print(\"Waiting for messages\")\n\n    consumer = VTConsumer(args.VTAPIKey, connection)\n    channel.basic_consume(consumer.consume_message, queue='lookup')\n\n    channel.start_consuming()\n\n    connection.close()\n\nif __name__ == '__main__':\n    main()"
  },
  {
    "path": "ACE-Docker/ace-sql/Dockerfile",
    "content": "FROM microsoft/mssql-server-linux\nMAINTAINER Jared Atkinson <jared@invoke-ir.com>\n\nENV ACCEPT_EULA Y\n\n# Create app directory\nRUN mkdir -p /usr/src/ace\nWORKDIR /usr/src/ace\n\n# Copy files to container\nCOPY import-data.sh /usr/src/ace\nCOPY ace.sql /usr/src/ace\n\n# Grant permissions for the import-data script to be executable\nRUN chmod +x /usr/src/ace/import-data.sh\n\nCMD /bin/bash /usr/src/ace/import-data.sh"
  },
  {
    "path": "ACE-Docker/ace-sql/README.md",
    "content": "Built on [microsoft/mssql-server-linux](https://hub.docker.com/r/microsoft/mssql-server-linux/), this images provides the backend database used by the [ACE Web Application](https://github.com/Invoke-IR/ACE/tree/master/ACE-WebService).\n \n## Requirements\n* This image requires Docker Engine 1.8+ in any of their supported platforms.\n* At least 3.25 GB of RAM. Make sure to assign enough memory to the Docker VM if you're running on Docker for Mac or Windows.\n* Requires the following environment flags\n* SA_PASSWORD=<your_strong_password>\n* A strong system administrator (SA) password: At least 8 characters including uppercase, lowercase letters, base-10 digits and/or non-alphanumeric symbols.\n\n## Using this Image\n### Run\n```\ndocker run --name ace-sql -e 'SA_PASSWORD=yourStrong(!)Password' -e 'MSSQL_PID=Standard' -p 1433:1433 -d specterops/ace-sql\n```\n### For Persistence\nIf you desire your RabbitMQ data and setting to persist between containers, you need to create a docker volume `docker volume create sql-data` then add `-v sql-data:/var/opt/mssql` to the docker run command\n\n### Environment Variables\n* **SA_PASSWORD** is the database system administrator (userid = 'sa') password used to connect to SQL Server once the container is running. Important note: This password needs to include at least 8 characters of at least three of these four categories: uppercase letters, lowercase letters, numbers and non-alphanumeric symbols."
  },
  {
    "path": "ACE-Docker/ace-sql/ace.sql",
    "content": "CREATE TABLE [dbo].[Credentials] (\n    [Id]       UNIQUEIDENTIFIER NOT NULL,\n    [Password] NVARCHAR (MAX)   NOT NULL,\n    [UserName] NVARCHAR (MAX)   NOT NULL,\n    CONSTRAINT [PK_Credentials] PRIMARY KEY CLUSTERED ([Id] ASC)\n);\n\nCREATE TABLE [dbo].[Computers] (\n    [Id]              UNIQUEIDENTIFIER NOT NULL,\n    [ComputerName]    NVARCHAR (MAX)   NULL,\n    [CredentialId]    UNIQUEIDENTIFIER NOT NULL,\n    [OperatingSystem] NVARCHAR (MAX)   NULL,\n    [RPC]             BIT              NOT NULL,\n    [SMB]             BIT              NOT NULL,\n    [SSH]             BIT              NOT NULL,\n    [Scanned]         BIT              NOT NULL,\n    [WinRM]           BIT              NOT NULL,\n    CONSTRAINT [PK_Computers] PRIMARY KEY CLUSTERED ([Id] ASC),\n    CONSTRAINT [FK_Computers_Credentials_CredentialId] FOREIGN KEY ([CredentialId]) REFERENCES [dbo].[Credentials] ([Id]) ON DELETE CASCADE\n);\n\nGO\nCREATE NONCLUSTERED INDEX [IX_Computers_CredentialId]\n    ON [dbo].[Computers]([CredentialId] ASC);\n\nCREATE TABLE [dbo].[Scans] (\n    [Id]              UNIQUEIDENTIFIER NOT NULL,\n    [ComputerId]      UNIQUEIDENTIFIER NOT NULL,\n    [StartTime]       DATETIME2 (7)    NOT NULL,\n    [Status]          NVARCHAR (MAX)   NULL,\n    [StopTime]        DATETIME2 (7)    NOT NULL,\n    [SweepIdentifier] UNIQUEIDENTIFIER DEFAULT ('00000000-0000-0000-0000-000000000000') NOT NULL,\n    CONSTRAINT [PK_Scans] PRIMARY KEY CLUSTERED ([Id] ASC),\n    CONSTRAINT [FK_Scans_Computers_ComputerId] FOREIGN KEY ([ComputerId]) REFERENCES [dbo].[Computers] ([Id]) ON DELETE CASCADE\n);\n\nCREATE TABLE [dbo].[Scripts] (\n    [Id]             UNIQUEIDENTIFIER NOT NULL,\n    [CreationTime]   DATETIME2 (7)    NOT NULL,\n    [Language]       NVARCHAR (MAX)   NOT NULL,\n    [LastUpdateTime] DATETIME2 (7)    NOT NULL,\n    [Name]           NVARCHAR (MAX)   NOT NULL,\n    [Uri]            NVARCHAR (MAX)   NOT NULL,\n    [RoutingKey]     NVARCHAR (MAX)   NOT NULL,\n    CONSTRAINT [PK_Scripts] PRIMARY KEY CLUSTERED ([Id] ASC)\n);\n\nCREATE TABLE [dbo].[Downloads] (\n    [Id]           UNIQUEIDENTIFIER NOT NULL,\n    [ComputerName] NVARCHAR (MAX)   NOT NULL,\n    [Content]      VARBINARY (MAX)  NOT NULL,\n    [DownloadTime] DATETIME2 (7)    NOT NULL,\n    [FullPath]     NVARCHAR (MAX)   NOT NULL,\n    [Name]         NVARCHAR (MAX)   NOT NULL,\n    CONSTRAINT [PK_Downloads] PRIMARY KEY CLUSTERED ([Id] ASC)\n);\n\nCREATE TABLE [dbo].[Schedules] (\n    [Id]             UNIQUEIDENTIFIER NOT NULL,\n    [ExecutionCount] INT              NOT NULL,\n    [StartTime]      DATETIME2 (7)    NOT NULL,\n    [JobName]        NVARCHAR (MAX)   NULL,\n    [TriggerName]    NVARCHAR (MAX)   NULL,\n    [ScriptId]       NVARCHAR (MAX)   NULL,\n    [RepeatCount]    INT              DEFAULT ((0)) NOT NULL,\n    CONSTRAINT [PK_Schedules] PRIMARY KEY CLUSTERED ([Id] ASC)\n);\n\nCREATE TABLE [dbo].[Sweeps] (\n    [Id]            UNIQUEIDENTIFIER NOT NULL,\n    [CompleteCount] INT              NOT NULL,\n    [EndTime]       DATETIME2 (7)    NOT NULL,\n    [ScanCount]     INT              NOT NULL,\n    [StartTime]     DATETIME2 (7)    NOT NULL,\n    [Status]        NVARCHAR (MAX)   NULL,\n    [ErrorCount]    INT              DEFAULT ((0)) NOT NULL,\n    CONSTRAINT [PK_Sweeps] PRIMARY KEY CLUSTERED ([Id] ASC)\n);\n\nCREATE TABLE [dbo].[Users] (\n    [Id]        UNIQUEIDENTIFIER NOT NULL,\n    [ApiKey]    NVARCHAR (MAX)   NOT NULL,\n    [FirstName] NVARCHAR (MAX)   NULL,\n    [IsAdmin]   BIT              NOT NULL,\n    [LastName]  NVARCHAR (MAX)   NULL,\n    [UserName]  NVARCHAR (MAX)   NOT NULL,\n    CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED ([Id] ASC)\n);\n\nINSERT INTO [dbo].[Users] ([Id], [ApiKey], [FirstName], [IsAdmin], [LastName], [UserName]) VALUES (N'334d89c9-da7a-43e8-a648-5dc8b22019ed', N'[APIKEY]', N'Admin', 1, N'Admin', N'admin')"
  },
  {
    "path": "ACE-Docker/ace-sql/import-data.sh",
    "content": "/opt/mssql/bin/sqlservr > /dev/null &\n\n#wait for the SQL Server to come up\nsleep 45s\n\n\n# Check if the database already exists\n/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P $SA_PASSWORD -d ACEWebService -Q \"SELECT * FROM dbo.Scripts\" >> /dev/null 2>&1\nERROR=$?\n\nif [ $ERROR -ne 0 ]; then\n  # Create Unique API Key\n  apikey=$(cat /proc/sys/kernel/random/uuid)\n  sed -i -e 's/\\[APIKEY\\]/'\"$apikey\"'/g' /usr/src/ace/ace.sql\n\n  #run the setup script to create the DB and the schema in the DB\n  /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P $SA_PASSWORD -Q \"CREATE DATABASE ACEWebService\" > /dev/null\n  /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P $SA_PASSWORD -d ACEWebService -i /usr/src/ace/ace.sql > /dev/null\nelse\n  # We need to return the ApiKey\n  apikey=\"$(/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P $SA_PASSWORD -d ACEWebService -Q \"SELECT ApiKey FROM dbo.Users WHERE Id='334D89C9-DA7A-43E8-A648-5DC8B22019ED'\" | grep -E '[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}')\"\nfi\n\necho \"\\\"ApiKey\\\": \\\"$apikey\\\",\"\necho \"\\\"SQLPassword\\\": \\\"$SA_PASSWORD\\\"\"\n#echo \"\\\"DefaultConnection\\\": \\\"Server=sql.ace.local;Database=ACEWebService;User Id=sa;Password=$SA_PASSWORD;MultipleActiveResultSets=true\\\"\"\n\nwhile true; do\nsleep 300\ndone"
  },
  {
    "path": "ACE-Docker/ace.env",
    "content": "SA_PASSWORD=P@ssw0rd!\nMSSQL_PID=Standard\nRABBITMQ_DEFAULT_USER=ace\nRABBITMQ_DEFAULT_PASS=P@ssw0rd!\nAPIKEY=YOURAPIKEYHERE\nWEBSERVICE_IP=192.168.1.10"
  },
  {
    "path": "ACE-Docker/docker-compose.yml",
    "content": "version: '2.1'\nnetworks:\n  ace:\n    driver: bridge\n    ipam:\n      config:\n        - subnet: 172.18.0.0/16\nservices:\n  ace-rabbitmq:\n    image: specterops/ace-rabbitmq\n    container_name: ace-rabbitmq\n    env_file: ./ace.env\n    hostname: ace-rabbitmq\n    networks:\n      ace:\n        ipv4_address: 172.18.0.2\n        aliases:\n          - rabbitmq.ace.local\n    ports: \n      - 5672:5672\n      - 15672:15672\n  ace-sql:\n    image: specterops/ace-sql\n    container_name: ace-sql\n    env_file: ./ace.env\n    hostname: ace-sql\n    networks:\n      ace:\n        aliases:\n          - sql.ace.local\n        ipv4_address: 172.18.0.3\n    ports: \n      - 1433:1433\n  ace-nginx:\n    image: specterops/ace-nginx\n    container_name: ace-nginx\n    env_file: ./ace.env\n    hostname: ace-nginx\n    networks:\n      ace:\n        aliases:\n          - nginx.ace.local\n        ipv4_address: 172.18.0.4\n    ports:\n      - \"80:80\"\n      - \"443:443\""
  },
  {
    "path": "ACE-Docker/settings.sh",
    "content": "clear\n\nget_host_ip(){\n    # *********** Getting Host IP ***************\n    # https://github.com/Invoke-IR/ACE/blob/master/ACE-Docker/start.sh\n    echo \"[ACE-INSTALLATION-INFO] Obtaining current host IP..\"\n    unameOut=\"$(uname -s)\"\n    case \"${unameOut}\" in\n        Linux*)     host_ip=$(ip route get 1 | awk '{print $NF;exit}');;\n        Darwin*)    host_ip=$(ifconfig en0 | grep inet | grep -v inet6 | cut -d ' ' -f2);;\n        *)          host_ip=\"UNKNOWN:${unameOut}\"\n    esac\n}\n\n# Write appsettings.Production.json to screen\nget_appsettings_data(){\n  echo \"\"\n  echo \"\"\n  echo \"==========================================================\"\n  echo \"\"\n  echo \"    \\\"RabbitMQServer\\\": \\\"${host_ip}\\\"\"\n  echo \"    $(docker logs ace-rabbitmq | grep UserName)\"\n  echo \"    $(docker logs ace-rabbitmq | grep Password)\"\n  echo \"    $(docker logs ace-nginx | grep Thumbprint)\"\n  echo \"    \\\"SQLServer\\\": \\\"${host_ip}\\\"\"\n  echo \"    $(docker logs ace-sql | grep SQLPassword)\"\n  echo \"\"\n  echo \"==========================================================\"\n  echo \"\"\n  echo \"\"\n}\n\nget_ps_settings(){\n# Provide configuration details for PowerShell Module\n  echo \"\"\n  echo \"\"\n  echo \"===============================================================\"\n  echo \"|        Thank you for provisioning ACE with Docker!!         |\"\n  echo \"|  Please use the following information to interact with ACE  |\"\n  echo \"===============================================================\"\n  echo \"\" \n  echo \"  \\$settings = @{\"\n  echo \"    Uri        = 'https://${host_ip}'\"\n  IFS='\"' read -r -a array <<< \"$(docker logs ace-sql | grep Api)\"\n  echo \"    ApiKey     = '${array[3]}'\"\n  IFS='\"' read -r -a array <<< \"$(docker logs ace-nginx | grep Thumbprint)\"\n  echo \"    Thumbprint = '${array[3]}'\"\n  echo \"  }\"\n  echo \"\"\n  echo \"==============================================================\"\n  echo \"\"\n  echo \"\"\n}\n\nget_host_ip\nget_appsettings_data\nget_ps_settings\n"
  },
  {
    "path": "ACE-Docker/start.sh",
    "content": "# Get directory of script and change to it\nDIR=\"$( cd \"$( dirname \"${BASH_SOURCE[0]}\" )\" && pwd )\"\ncd $DIR\n\n# *********** Check if user is root ***************\nif [[ $EUID -ne 0 ]]; then\n   echo \"[ACE-INSTALLATION-INFO] YOU MUST BE ROOT TO RUN THIS SCRIPT!!!\" \n   exit 1\nfi\n\nLOGFILE=\"/var/log/ace-install.log\"\nechoerror() {\n    printf \"${RC} * ERROR${EC}: $@\\n\" 1>&2;\n}\n\n# *********** Check System Kernel Name ***************\nsystemKernel=\"$(uname -s)\"\n\ninstall_docker(){\n  if [ \"${systemKernel}\" == \"Linux\" ]; then\n      # Reference: https://get.docker.com/\n      echo \"[ACE-DOCKER-INSTALLATION-INFO] ACE identified Linux as the system kernel\"\n      echo \"[ACE-DOCKER-INSTALLATION-INFO] Checking distribution list and version\"\n      # *********** Check distribution list ***************\n      lsb_dist=\"$(. /etc/os-release && echo \"$ID\")\"\n      lsb_dist=\"$(echo \"$lsb_dist\" | tr '[:upper:]' '[:lower:]')\"\n\n      # *********** Check distribution version ***************\n      case \"$lsb_dist\" in\n          ubuntu)\n              if [ -x \"$(command -v lsb_release)\" ]; then\n                  dist_version=\"$(lsb_release --codename | cut -f2)\"\n              fi\n              if [ -z \"$dist_version\" ] && [ -r /etc/lsb-release ]; then\n                  dist_version=\"$(. /etc/lsb-release && echo \"$DISTRIB_CODENAME\")\"\n              fi\n          ;;\n          debian|raspbian)\n              dist_version=\"$(sed 's/\\/.*//' /etc/debian_version | sed 's/\\..*//')\"\n              case \"$dist_version\" in\n                  9)\n                      dist_version=\"stretch\"\n                  ;;\n                  8)\n                      dist_version=\"jessie\"\n                  ;;\n                  7)\n                      dist_version=\"wheezy\"\n                  ;;\n              esac\n          ;;\n          centos)\n              if [ -z \"$dist_version\" ] && [ -r /etc/os-release ]; then\n                  dist_version=\"$(. /etc/os-release && echo \"$VERSION_ID\")\"\n              fi\n          ;;\n          rhel|ol|sles)\n              ee_notice \"$lsb_dist\"\n              #exit 1\n              ;;\n          *)\n              if [ -x \"$(command -v lsb_release)\"]; then\n                  dist_version=\"$(lsb_release --release | cut -f2)\"\n              fi\n              if [ -z \"$dist_version\" ] && [ -r /etc/os-release ]; then\n                  dist_version=\"$(. /etc/os-release && echo \"$VERSION_ID\")\"\n              fi\n          ;;\n      esac\n      echo \"[ACE-DOCKER-INSTALLATION-INFO] You're using $lsb_dist version $dist_version\"            \n      ERROR=$?\n      if [ $ERROR -ne 0 ]; then\n          echoerror \"Could not verify distribution or version of the OS (Error Code: $ERROR).\"\n      fi\n\n      # *********** Check if docker is installed ***************\n      if [ -x \"$(command -v docker)\" ]; then\n          echo \"[ACE-DOCKER-INSTALLATION-INFO] Docker already installed\"\n          echo \"[ACE-DOCKER-INSTALLATION-INFO] Dockerizing ACE..\"\n      else\n          echo \"[ACE-DOCKER-INSTALLATION-INFO] Docker is not installed\"\n          echo \"[ACE-DOCKER-INSTALLATION-INFO] Checking if curl is installed first\"\n          if [ -x \"$(command -v curl)\" ]; then\n              echo \"[ACE-DOCKER-INSTALLATION-INFO] curl is already installed\"\n              echo \"[ACE-DOCKER-INSTALLATION-INFO] Ready to install  Docker..\"\n          else\n              echo \"[ACE-DOCKER-INSTALLATION-INFO] curl is not installed\"\n              echo \"[ACE-DOCKER-INSTALLATION-INFO] Installing curl before installing docker..\"\n              apt-get install -y curl >> $LOGFILE 2>&1\n              ERROR=$?\n              if [ $ERROR -ne 0 ]; then\n                  echoerror \"Could not install curl (Error Code: $ERROR).\"\n                  #exit 1\n              fi\n          fi\n          # ****** Installing via convenience script ***********\n          echo \"[ACE-DOCKER-INSTALLATION-INFO] Installing docker via convenience script..\"\n          curl -fsSL get.docker.com -o /tmp/get-docker.sh >> $LOGFILE 2>&1\n          chmod +x /tmp/get-docker.sh >> $LOGFILE 2>&1\n          /tmp/get-docker.sh >> $LOGFILE 2>&1\n          ERROR=$?\n          if [ $ERROR -ne 0 ]; then\n              echoerror \"Could not install docker via convenience script (Error Code: $ERROR).\"\n              #exit 1\n          fi\n          # ****** Installing docker-compose ***********\n          echo \"[ACE-DOCKER-INSTALLATION-INFO] Installing docker-compose ..\"\n          curl -L https://github.com/docker/compose/releases/download/1.19.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose >> $LOGFILE 2>&1\n          chmod +x /usr/local/bin/docker-compose >> $LOGFILE 2>&1\n          ERROR=$?\n          if [ $ERROR -ne 0 ]; then\n              echoerror \"Could not install docker-compose (Error Code: $ERROR).\"\n              exit 1\n          fi\n      fi\n  else\n      # *********** Check if docker is installed ***************\n      if [ -x \"$(command -v docker)\" ]; then\n          echo \"[ACE-DOCKER-INSTALLATION-INFO] Docker already installed\"\n          echo \"[ACE-DOCKER-INSTALLATION-INFO] Dockerizing ACE..\"\n      else\n          echo \"[ACE-DOCKER-INSTALLATION-INFO] Install docker for $systemKernel\"\n          #exit 1\n      fi\n  fi\n}\n\nget_host_ip(){\n    # *********** Getting Host IP ***************\n    # https://github.com/Invoke-IR/ACE/blob/master/ACE-Docker/start.sh\n    echo \"[ACE-INSTALLATION-INFO] Obtaining current host IP..\"\n    unameOut=\"$(uname -s)\"\n    case \"${unameOut}\" in\n        Linux*)     host_ip=$(ip route get 1 | awk '{print $NF;exit}');;\n        Darwin*)    host_ip=$(ifconfig en0 | grep inet | grep -v inet6 | cut -d ' ' -f2);;\n        *)          host_ip=\"UNKNOWN:${unameOut}\"\n    esac\n    \n    # *********** Accepting Defaults or Allowing user to set ACE IP ***************\n    local ip_choice\n    local read_input\n    read -t 30 -p \"[ACE-INSTALLATION-INFO] Set ACE IP. Default value is your current IP: \" -e -i ${host_ip} ip_choice\n    read_input=$?\n    ip_choice=\"${ip_choice:-$host_ip}\"\n    if [ $ip_choice != $host_ip ]; then\n        host_ip=$ip_choice\n    fi\n    if [ $read_input  = 142 ]; then\n       echo -e \"\\n[ACE-INSTALLATION-INFO] ACE IP set to ${host_ip}\" \n    else\n    echo \"[ACE-INSTALLATION-INFO] ACE IP set to ${host_ip}\"\n    fi\n}\n\n# Write appsettings.Production.json to screen\nget_appsettings_data(){\n  echo \"\"\n  echo \"\"\n  echo \"==========================================================\"\n  echo \"\"\n  echo \"    \\\"RabbitMQServer\\\": \\\"${host_ip}\\\"\"\n  echo \"    $(docker logs ace-rabbitmq | grep UserName)\"\n  echo \"    $(docker logs ace-rabbitmq | grep Password)\"\n  echo \"    $(docker logs ace-nginx | grep Thumbprint)\"\n  echo \"    \\\"SQLServer\\\": \\\"${host_ip}\\\"\"\n  echo \"    $(docker logs ace-sql | grep SQLPassword)\"\n  echo \"\"\n  echo \"==========================================================\"\n  echo \"\"\n  echo \"\"\n}\n\nget_ps_settings(){\n# Provide configuration details for PowerShell Module\n  echo \"\"\n  echo \"\"\n  echo \"===============================================================\"\n  echo \"|        Thank you for provisioning ACE with Docker!!         |\"\n  echo \"|  Please use the following information to interact with ACE  |\"\n  echo \"===============================================================\"\n  echo \"\" \n  echo \"  \\$settings = @{\"\n  echo \"    Uri        = 'https://${host_ip}'\"\n  IFS='\"' read -r -a array <<< \"$(docker logs ace-sql | grep Api)\"\n  echo \"    ApiKey     = '${array[3]}'\"\n  IFS='\"' read -r -a array <<< \"$(docker logs ace-nginx | grep Thumbprint)\"\n  echo \"    Thumbprint = '${array[3]}'\"\n  echo \"  }\"\n  echo \"\"\n  echo \"==============================================================\"\n  echo \"\"\n  echo \"\"\n}\n\n# Test if Docker and Docker-Compose are installed\ninstall_docker\n\n# Get the IP Address for later\nget_host_ip\n\n# Build Docker Images and Start Containers\necho \"[ACE-INSTALLATION-INFO] Building ACE Docker Containers\"\ndocker-compose build >> $LOGFILE 2>&1\necho \"[ACE-INSTALLATION-INFO] Starting ACE Docker Images\"\ndocker-compose up -d >> $LOGFILE 2>&1\n\necho \"[ACE-INSTALLATION-INFO] Waiting for Docker Images to Start\"\nsleep 60\n\nget_appsettings_data\nget_ps_settings"
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/Download-AceFile.ps1",
    "content": "﻿function Download-AceFile\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory)]\n        [string]\n        $ApiKey,\n\n        [Parameter(Mandatory)]\n        [string]\n        $Thumbprint,\n\n        [Parameter(Mandatory)]\n        [Guid]\n        $ComputerId,\n\n        [Parameter(Mandatory)]\n        [string]\n        $FilePath\n    )\n\n    $body = @{\n        Uri = $Uri\n        ComputerId = $ComputerId\n        FilePath = $FilePath\n    }\n\n    try \n    {\n        $result = Invoke-AceWebRequest -Method Post -Uri \"$($Uri)/ace/download\" -Body (ConvertTo-Json $body -Compress) -ContentType application/json -ApiKey $ApiKey -Thumbprint $Thumbprint\n        Write-Output ($result | ConvertFrom-Json)        \n    }\n    catch \n    {\n       Write-Warning \"test\" \n    }\n}"
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/Get-AceComputer.ps1",
    "content": "function Get-AceComputer\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory)]\n        [string]\n        $ApiKey,\n\n        [Parameter(Mandatory)]\n        [string]\n        $Thumbprint,\n\n        [Parameter()]\n        [Guid]\n        $Id\n    )\n\n    if ($PSBoundParameters.ContainsKey('Id'))\n    {\n        $Url = \"$($Uri)/ace/computer/$($Id)\"\n    }\n    else\n    {\n        $Url = \"$($Uri)/ace/computer\"\n    }\n    \n    try\n    {\n        $result = Invoke-AceWebRequest -Method Get -Uri $Url -ApiKey $ApiKey -Thumbprint $Thumbprint -ErrorAction Stop\n        Write-Output ($result | ConvertFrom-Json)\n    }\n    catch\n    {\n\n    }   \n}"
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/Get-AceCredential.ps1",
    "content": "﻿function Get-AceCredential\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory)]\n        [string]\n        $Uri,\n        \n        [Parameter(Mandatory)]\n        [string]\n        $ApiKey,\n\n        [Parameter(Mandatory)]\n        [string]\n        $Thumbprint,\n\n        [Parameter()]\n        [Guid]\n        $Id\n    )\n    \n    try\n    {\n        if($PSBoundParameters.ContainsKey('Id'))\n        {\n            $result = Invoke-AceWebRequest -Method Get -Uri \"$($Uri)/ace/credential/pscredential/$($Id)\" -ApiKey $ApiKey -Thumbprint $Thumbprint -ErrorAction Stop\n            $result = $result | ConvertFrom-Json\n            $secpassword = ConvertTo-SecureString -String $result.password -AsPlainText -Force\n            $cred = New-Object -TypeName System.Management.Automation.PSCredential($result.userName, $secpassword)\n            Write-Output $cred\n        }\n        else\n        {\n            $result = Invoke-AceWebRequest -Method Get -Uri \"$($Uri)/ace/credential\" -ApiKey $ApiKey -Thumbprint $Thumbprint -ErrorAction Stop\n            Write-Output ($result | ConvertFrom-Json)\n        }\n    }\n    catch\n    {\n        \n    }\n}"
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/Get-AceSchedule.ps1",
    "content": "function Get-AceSchedule\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory)]\n        [string]\n        $ApiKey,\n\n        [Parameter(Mandatory)]\n        [string]\n        $Thumbprint        \n    )\n\n    try\n    {\n        $result = Invoke-AceWebRequest -Method Get -Uri \"$($Uri)/ace/schedule\" -ApiKey $ApiKey -Thumbprint $Thumbprint -ErrorAction Stop\n        Write-Output ($result | ConvertFrom-Json)        \n    }\n    catch\n    {\n        \n    }\n}"
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/Get-AceScript.ps1",
    "content": "function Get-AceScript\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory)]\n        [string]\n        $ApiKey,\n\n        [Parameter(Mandatory)]\n        [string]\n        $Thumbprint        \n    )\n\n    try\n    {\n        $result = Invoke-AceWebRequest -Method Get -Uri \"$($Uri)/ace/script\" -ApiKey $ApiKey -Thumbprint $Thumbprint -ErrorAction Stop\n        Write-Output ($result | ConvertFrom-Json)        \n    }\n    catch\n    {\n        \n    }\n}"
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/Get-AceSweep.ps1",
    "content": "function Get-AceSweep\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory)]\n        [string]\n        $ApiKey,\n\n        [Parameter(Mandatory)]\n        [string]\n        $Thumbprint,\n\n        [Parameter()]\n        [Guid]\n        $Id\n    )\n\n    if ($PSBoundParameters.ContainsKey('Id'))\n    {\n        $Url = \"$($Uri)/ace/sweep/$($Id)\"\n    }\n    else\n    {\n        $Url = \"$($Uri)/ace/sweep\"\n    }\n\n    try\n    {\n        $result = Invoke-AceWebRequest -Method Get -Uri $Url -ApiKey $ApiKey -Thumbprint $Thumbprint -ErrorAction Stop\n        Write-Output ($result | ConvertFrom-Json)        \n    }\n    catch\n    {\n        \n    }\n}"
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/Get-AceSweepResult.ps1",
    "content": "function Get-AceSweepResult\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory)]\n        [string]\n        $ApiKey,\n\n        [Parameter(Mandatory)]\n        [string]\n        $Thumbprint,\n\n        [Parameter()]\n        [Guid]\n        $Id\n    )\n\n    try\n    {\n        $result = Invoke-AceWebRequest -Method Get -Uri \"$($Uri)/ace/scan/$($Id)\" -ApiKey $ApiKey -Thumbprint $Thumbprint -ErrorAction Stop\n        Write-Output ($result | ConvertFrom-Json)        \n    }\n    catch\n    {\n        \n    }\n}"
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/Get-AceUser.ps1",
    "content": "function Get-AceUser\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory)]\n        [string]\n        $ApiKey,\n\n        [Parameter(Mandatory)]\n        [string]\n        $Thumbprint        \n    )\n\n    try\n    {\n        $result = Invoke-AceWebRequest -Method Get -Uri \"$($Uri)/ace/user\" -ApiKey $ApiKey -Thumbprint $Thumbprint -ErrorAction Stop\n        Write-Output ($result | ConvertFrom-Json)        \n    }\n    catch\n    {\n        \n    }\n}"
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/Invoke-AceWebRequest.ps1",
    "content": "function Invoke-AceWebRequest\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $ApiKey,\n\n        [Parameter(Mandatory)]\n        [string]\n        $Thumbprint,\n\n        [Parameter()]\n        [ValidateSet('Delete','Get','Post','Put')]\n        [string]\n        $Method = 'Get',\n\n        [Parameter()]\n        [string]\n        $ContentType = 'application/json',\n\n        [Parameter()]\n        [string]\n        $Body\n    )\n    \n    try\n    {\n        # Create web request\n        $WebRequest = [System.Net.WebRequest]::Create($Uri)\n    \n        $WebRequest.Headers.Add('X-API-Version:1.0')\n        $webrequest.Headers.Add(\"X-ApiKey:$($ApiKey)\")\n\n        $WebRequest.Method = $Method\n        $WebRequest.ContentType = $ContentType\n\n        # Set the callback to check for null certificate and thumbprint matching.\n        $WebRequest.ServerCertificateValidationCallback = {\n            \n            $certificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]$args[1]\n            \n            if ($certificate -eq $null)\n            {\n                $Host.UI.WriteWarningLine(\"Null certificate.\")\n                return $true\n            }\n    \n            if ($certificate.Thumbprint -eq $Thumbprint)\n            {\n                return $true\n            }\n            else\n            {\n                $Host.UI.WriteWarningLine(\"Thumbprint mismatch. Certificate thumbprint $($certificate.Thumbprint)\")\n                $Host.UI.WriteWarningLine(\"   Expected thumbprint: $($Thumbprint)\")\n                $Host.UI.WriteWarningLine(\"   Received thumbprint: $($certificate.Thumbprint)\")\n            }\n    \n            return $false\n        }\n\n        if($PSBoundParameters.ContainsKey('Body'))\n        {\n            $byteArray = [System.Text.Encoding]::UTF8.GetBytes($Body)\n            $Webrequest.ContentLength = $byteArray.Length\n            \n            $dataStream = $Webrequest.GetRequestStream()            \n            $dataStream.Write($byteArray, 0, $byteArray.Length)\n            $dataStream.Close()\n        }\n\n        # Get response stream\n        $ResponseStream = $webrequest.GetResponse().GetResponseStream()\n    \n        # Create a stream reader and read the stream returning the string value.\n        $StreamReader = New-Object System.IO.StreamReader -ArgumentList $ResponseStream\n        $StreamReader.ReadToEnd()\n\n        $StreamReader.Close()\n        $ResponseStream.Close()\n    }\n    catch\n    {\n        Write-Error \"Failed: $($_.exception.innerexception.message)\"\n    }\n}"
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/New-AceCredential.ps1",
    "content": "function New-AceCredential\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory)]\n        [string]\n        $ApiKey,\n\n        [Parameter(Mandatory)]\n        [string]\n        $Thumbprint,        \n\n        [Parameter(Mandatory)]\n        [Management.Automation.PSCredential]\n        [Management.Automation.CredentialAttribute()]\n        $Credential\n    )\n\n    $body = @{\n        UserName = $Credential.UserName\n        Password = $Credential.GetNetworkCredential().Password\n    }\n\n    try \n    {\n        $result = Invoke-AceWebRequest -Method Post -Uri \"$($Uri)/ace/credential\" -Body (ConvertTo-Json $body -Compress) -ContentType application/json -ApiKey $ApiKey -Thumbprint $Thumbprint\n        Write-Output ($result | ConvertFrom-Json)    \n    }\n    catch \n    {\n        \n    }\n}"
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/New-AceScheduledScan.ps1",
    "content": "function New-AceScheduledScan\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory)]\n        [string[]]\n        $ComputerId,\n\n        [Parameter(Mandatory)]\n        [string]\n        $ScriptId,\n\n        [Parameter(Mandatory)]\n        [string]\n        $Uri,\n        \n        [Parameter(Mandatory)]\n        [string]\n        $ApiKey,\n\n        [Parameter(Mandatory)]\n        [string]\n        $Thumbprint,\n\n        [Parameter(Mandatory)]\n        [Int32]\n        $Hour,\n\n        [Parameter(Mandatory)]\n        [Int32]\n        $Minute,\n\n        [Parameter(Mandatory)]\n        [Int32]\n        $IntervalInMinutes,\n\n        [Parameter()]\n        [Int32]\n        $RepeatCount = 0\n    )\n\n    $body = @{\n        ComputerId = $ComputerId\n        ScriptId = $ScriptId\n        Uri = $Uri\n        Hour = $Hour\n        Minute = 0\n        Interval = $IntervalInMinutes\n        RepeatCount = $RepeatCount\n    }\n\n    $result = Invoke-AceWebRequest -Method Post -Uri \"$($Uri)/ace/schedule\" -Body (ConvertTo-Json $body -Compress) -ContentType application/json -ApiKey $ApiKey -Thumbprint $Thumbprint\n    Write-Output ($result | ConvertFrom-Json)        \n}"
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/New-AceScript.ps1",
    "content": "function New-AceScript\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory)]\n        [string]\n        $ApiKey,\n\n        [Parameter(Mandatory)]\n        [string]\n        $Thumbprint,\n\n        [Parameter(Mandatory)]\n        [string]\n        $Path,\n\n        [Parameter(Mandatory)]\n        [string]\n        $Name,\n\n        [Parameter(Mandatory)]\n        [string]\n        $Language,\n        \n        [Parameter()]\n        [string]\n        $RoutingKey\n    )\n\n    $body = @{\n        Name = $Name\n        Language = $Language\n        RoutingKey = $RoutingKey\n        Content = [System.IO.File]::ReadAllBytes($Path)\n    }\n\n    try \n    {\n        $result = Invoke-AceWebRequest -Method Post -Uri \"$($Uri)/ace/script\" -Body (ConvertTo-Json $body -Compress) -ContentType application/json -ApiKey $ApiKey -Thumbprint $Thumbprint\n        Write-Output ($result | ConvertFrom-Json)        \n    }\n    catch \n    {\n        \n    }\n}"
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/New-AceUser.ps1",
    "content": "function New-AceUser\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory)]\n        [string]\n        $ApiKey,\n\n        [Parameter(Mandatory)]\n        [string]\n        $Thumbprint,\n\n        [Parameter(Mandatory)]\n        [string]\n        $UserName,\n        \n        [Parameter()]\n        [string]\n        $FirstName = $null,\n\n        [Parameter()]\n        [string]\n        $LastName = $null,\n\n        [Parameter()]\n        [bool]\n        $IsAdmin = $false\n    )\n\n    $body = @{\n        UserName = $UserName\n        FirstName = $FirstName\n        LastName = $LastName\n        IsAdmin = $IsAdmin\n    }\n\n    try \n    {\n        $result = Invoke-AceWebRequest -Method Post -Uri \"$($Uri)/ace/user\" -Body (ConvertTo-Json $body -Compress) -ContentType application/json -ApiKey $ApiKey -Thumbprint $Thumbprint\n        Write-Output ($result | ConvertFrom-Json)        \n    }\n    catch \n    {\n        \n    }\n}"
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/Remove-AceCredential.ps1",
    "content": "function Remove-AceCredential\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory)]\n        [string]\n        $ApiKey,\n\n        [Parameter(Mandatory)]\n        [string]\n        $Thumbprint,\n\n        [Parameter(Mandatory)]\n        [Guid]\n        $Id\n    )\n\n    try\n    {\n        $result = Invoke-AceWebRequest -Method Get -Uri \"$($Uri)/ace/credential/delete/$($Id)\" -ApiKey $ApiKey -Thumbprint $Thumbprint\n        Write-Output ($result | ConvertFrom-Json)   \n    }\n    catch\n    {\n        \n    }\n}"
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/Remove-AceScript.ps1",
    "content": "function Remove-AceScript\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory)]\n        [string]\n        $ApiKey,\n\n        [Parameter(Mandatory)]\n        [string]\n        $Thumbprint,\n\n        [Parameter(Mandatory)]\n        [Guid]\n        $Id\n    )\n\n    try\n    {\n        $result = Invoke-AceWebRequest -Method Get -Uri \"$($Uri)/ace/script/delete/$($Id)\" -ApiKey $ApiKey -Thumbprint $Thumbprint\n        Write-Output ($result | ConvertFrom-Json)   \n    }\n    catch\n    {\n        \n    }\n}"
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/Remove-AceUser.ps1",
    "content": "function Remove-AceUser\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory)]\n        [string]\n        $ApiKey,\n\n        [Parameter(Mandatory)]\n        [string]\n        $Thumbprint,\n\n        [Parameter(Mandatory)]\n        [Guid]\n        $Id\n    )\n\n    try\n    {\n        $result = Invoke-AceWebRequest -Method Get -Uri \"$($Uri)/ace/user/delete/$($Id)\" -ApiKey $ApiKey -Thumbprint $Thumbprint\n        Write-Output ($result | ConvertFrom-Json)   \n    }\n    catch\n    {\n        \n    }\n}"
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/Send-AceResult.ps1",
    "content": "function Send-AceResult\n{\n    <#\n    .SYNOPSIS\n    Short description\n    \n    .DESCRIPTION\n    Long description\n    \n    .EXAMPLE\n    An example\n    \n    .NOTES\n    General notes\n\n    #>\n\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]\n        [psobject[]]\n        $InputObject,\n        \n        [Parameter(Mandatory)]\n        [string]\n        $Uri\n    )\n\n    begin\n    {\n        $header = @{\n            'X-API-Version' = '1.0'\n        }\n    }\n\n    process\n    {\n        foreach($o in $InputObject)\n        {\n            $result = Invoke-WebRequest -Method Post -Uri \"$($Uri)/ace/result/e989000d-2b98-44bd-94fc-403c41f42bf5\" -Body (ConvertTo-Json $o) -Headers $header -ContentType application/json\n\n            Write-Output ($result.Content | ConvertFrom-Json)\n        }\n    }\n\n    end\n    {\n\n    }\n}"
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/Start-AceDiscovery.ps1",
    "content": "function Start-AceDiscovery\n{\n    [CmdletBinding(DefaultParameterSetName = \"Domain\")]\n    param\n    (\n        [Parameter(Mandatory)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory)]\n        [string]\n        $ApiKey,\n        \n        [Parameter(Mandatory)]\n        [string]\n        $Thumbprint,\n\n        [Parameter(Mandatory)]\n        [Guid]\n        $CredentialId,\n\n        [Parameter(Mandatory, ParameterSetName = \"Domain\")]\n        [string]\n        $Domain,\n\n        [Parameter(Mandatory, ParameterSetName = \"ComputerList\")]\n        [string[]]\n        $ComputerName\n    )\n\n    switch($PSCmdlet.ParameterSetName)\n    {\n        ComputerList\n        {\n            $body = @{\n                ComputerName = $ComputerName\n                CredentialId = $CredentialId\n            }\n            \n            $result = Invoke-AceWebRequest -Method Post -Uri \"$($Uri)/ace/discover/computerlist\" -Body (ConvertTo-Json $body -Compress) -ContentType application/json -ApiKey $ApiKey -Thumbprint $Thumbprint\n        }\n        Domain\n        {\n            $body = @{\n                Domain = $Domain\n                CredentialId = $CredentialId\n            }\n\n            $result = Invoke-AceWebRequest -Method Post -Uri \"$($Uri)/ace/discover/domain\" -Body (ConvertTo-Json $body -Compress) -ContentType application/json -ApiKey $ApiKey -CheckCert\n        }\n    }\n\n    Write-Output ($result | ConvertFrom-Json)\n}"
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/Start-AceSweep.ps1",
    "content": "function Start-AceSweep\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory)]\n        [string]\n        $Uri,\n\n        [Parameter()]\n        [string]\n        $ExternalUri,\n\n        [Parameter(Mandatory)]\n        [string]\n        $ApiKey,\n\n        [Parameter(Mandatory)]\n        [string]\n        $Thumbprint,\n\n        [Parameter(Mandatory)]\n        [Guid[]]\n        $ComputerId,\n\n        [Parameter(Mandatory)]\n        [Guid]\n        $ScriptId      \n    )\n\n    if(-not $PSBoundParameters.ContainsKey('ExternalUri'))\n    {\n        $ExternalUri = $Uri\n    }\n\n    $body = @{\n        ComputerId = $ComputerId\n        ScriptId = $ScriptId\n        Uri = $Uri\n        ExternalUri = $ExternalUri\n    }\n\n    try\n    {\n        $result = Invoke-AceWebRequest -Method Post -Uri \"$($Uri)/ace/sweep\" -Body (ConvertTo-Json $body -Compress) -ContentType application/json -ApiKey $ApiKey -Thumbprint $Thumbprint\n        Write-Output ($result | ConvertFrom-Json)   \n    }\n    catch\n    {\n        \n    }\n}"
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/Update-AceCredential.ps1",
    "content": "function Update-AceCredential\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory)]\n        [string]\n        $ApiKey,\n\n        [Parameter(Mandatory)]\n        [string]\n        $Thumbprint,\n        \n        [Parameter(Mandatory)]\n        [Guid]\n        $CredentialId,\n\n        [Parameter(Mandatory)]\n        [Management.Automation.PSCredential]\n        [Management.Automation.CredentialAttribute()]\n        $Credential\n    )\n\n    $body = @{\n        UserName = $Credential.UserName\n        Password = $Credential.GetNetworkCredential().Password\n    }\n\n    $result = Invoke-AceWebRequest -Method Put -Uri \"$($Uri)/ace/credential/$($CredentialId)\" -Body (ConvertTo-Json $body) -ContentType application/json -ApiKey $ApiKey -Thumbprint $Thumbprint\n\n    Write-Output ($result.Content | ConvertFrom-Json)\n}"
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/Update-AceUser.ps1",
    "content": "function Update-AceUser\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory)]\n        [string]\n        $ApiKey,\n\n        [Parameter(Mandatory)]\n        [string]\n        $Thumbprint,\n\n        [Parameter(Mandatory)]\n        [string]\n        $UserId,\n\n        [Parameter(Mandatory)]\n        [string]\n        $UserName,\n        \n        [Parameter()]\n        [string]\n        $FirstName = $null,\n\n        [Parameter()]\n        [string]\n        $LastName = $null,\n\n        [Parameter()]\n        [bool]\n        $IsAdmin = $false\n    )\n    \n    $body = @{\n        UserName = $UserName\n        FirstName = $FirstName\n        LastName = $LastName\n        IsAdmin = $IsAdmin\n    }\n\n    $result = Invoke-AceWebRequest -Method Put -Uri \"$($Uri)/ace/user/$($UserId)\" -Body (ConvertTo-Json $body -Compress) -ContentType application/json -ApiKey $ApiKey -Thumbprint $Thumbprint\n    Write-Output ($result | ConvertFrom-Json)\n}"
  },
  {
    "path": "ACE-Management/PS-ACE/PS-ACE.psm1",
    "content": "Get-ChildItem \"$($PSScriptRoot)\\Cmdlets\\*\" -Include '*.ps1' |\n    ForEach-Object {. $_.FullName}"
  },
  {
    "path": "ACE-Management/PS-ACE/README.md",
    "content": "# PS-ACE\nThe ACE Web Application provides a RESTful API for managment and sweep tasking. PS-ACE is a PowerShell module that interacts with this API.\n\nThe supported mechanism for provisioning ACE is to use the start.sh script in the ACE-Docker directory. Upon completion, start.sh provides the user with all of the information required to interact with ACE's RESTful API. The three pieces of information necessary to interact with the ACE Web Application are:\n* Web Server URI\n* Builtin Administrator's API Key\n* Web Server's SSL Certificate Thumbprint\n\nBelow is an example of the output from start.sh:\n```\n==========================================================\n|      Thank you for provisioning ACE with Docker!!      |\n==========================================================\n\nPlease use the following information to interact with ACE:\n             Uri: https://10.57.106.141\n          ApiKey: 9C8DC642-268D-41EA-9521-43F718119FB7\n      Thumbprint: FA4608B93B017DF46D1BC6155DC4C5AF7D83EA1D\n\n==========================================================\n```\n\nThe best way to pass this information to the PS-ACE cmdlets is through a technique called [splatting](https://docs.microsoft.com/en-us/powershell/module/Microsoft.PowerShell.Core/about_Splatting?view=powershell-5.0). Splatting allows for a Hash Table to be passed as a set of parameter names (Keys) and values (Values) by using the '@' instead of the '$'.\n\nBelow is an example of creating a hash table called **props** with keys Uri, ApiKey, and Thumbprint (these are derived from the output of start.sh above) and using this hash table to splat **Get-AceUser**:\n\n```powershell\n# Create a hash table with ACE's common parameters\nPS> $props = @{\n    Uri = 'https://192.168.50.187'\n    ApiKey = 'd0bf91fa-9934-40ca-8cb9-5a1168546abc'\n    Thumbprint = '39F459D8CBE1D92396A435F6D5B375AED42CE518'\n}\n\n# Pass parameters through Splatting the props variable\nPS> Get-AceUser @props\n\nid        : 334d89c9-da7a-43e8-a648-5dc8b22019ed\nuserName  : admin\nfirstName : Admin\nlastName  : Admin\nisAdmin   : True\napiKey    : 9C8DC642-268D-41EA-9521-43F718119FB7\n```\n\n## Cmdlets\n### Get-AceComputer\n### Get-AceCredential\n### Get-AceSchedule\n### Get-AceScript\n### Get-AceSweep\n### Get-AceSweepResult\n### Get-AceUser\n### Invoke-AceWebRequest\n### New-AceCredential\n### New-AceScheduledScan\n### New-AceScript\n### New-AceUser\n### Remove-AceCredential\n### Remove-AceScript\n### Remove-AceUser\n### Send-AceResult\n### Start-AceDiscovery\n### Start-AceSweep\n### Update-AceCredential\n### Update-AceUser"
  },
  {
    "path": "ACE-Management/PS-ACE/Scripts/ACE-Master.ps1",
    "content": "﻿function Start-AceScript\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $SweepId,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $ScanId,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Thumbprint,\n\n        [Parameter()]\n        [ValidateSet('All','AccessToken','ArpCache','AtomTable','FullProcess','FullService','InjectedThread','KerberosTicket','LogonSession','MasterBootRecord','NetworkConnection','RegistryAutoRun','ScheduledTask','SecurityPackage','SimpleNamedPipe','WmiEventSubscription')]\n        [string[]]\n        $ScanType = 'All'\n\n    )\n\n    $HostFQDN = Get-WmiObject Win32_ComputerSystem -Property 'Name','Domain' | ForEach-Object {\"$($_.Name).$($_.Domain)\"}\n    $ResultDate = (Get-Date).ToString(\"yyyyMMddThhmmssmsmsZ\")\n\n    $scans = New-Object -TypeName System.Collections.Generic.List['Hashtable']\n    \n    if($ScanType -contains 'All' -or $ScanType -contains 'AccessToken')\n    {\n        $scans.Add(@{Function = 'Get-AccessToken'; RoutingKey = 'siem'; ScanType = 'AccessToken'})\n    }\n    if($ScanType -contains 'All' -or $ScanType -contains 'ArpCache')\n    {\n        $scans.Add(@{Function = 'Get-ArpCache -ReturnHashtables'; RoutingKey = 'siem'; ScanType = 'ArpCache'})\n    }\n    if($ScanType -contains 'All' -or $ScanType -contains 'AtomTable')\n    {\n        $scans.Add(@{Function = 'Get-AtomTable -ReturnHashtables'; RoutingKey = 'siem'; ScanType = 'AtomTable'})\n    }\n    if($ScanType -contains 'All' -or $ScanType -contains 'FullProcess')\n    {\n        $scans.Add(@{Function = 'Get-PSIProcess -ReturnHashtables'; RoutingKey = 'hash.siem'; ScanType = 'FullProcess'})\n    }    \n    if($ScanType -contains 'All' -or $ScanType -contains 'FullService')\n    {\n        $scans.Add(@{Function = 'Get-PSIService -ReturnHashtables'; RoutingKey = 'siem'; ScanType = 'FullService'})\n    }\n    if($ScanType -contains 'All' -or $ScanType -contains 'InjectedThread')\n    {    \n        $scans.Add(@{Function = 'Get-InjectedThread'; RoutingKey = 'siem'; ScanType = 'InjectedThread'})\n    }\n    if($ScanType -contains 'All' -or $ScanType -contains 'KerberosTicket')\n    {\n        $scans.Add(@{Function = 'Get-KerberosTicketCache'; RoutingKey = 'siem'; ScanType = 'KerberosTicket'})\n    }\n    if($ScanType -contains 'All' -or $ScanType -contains 'LogonSession')\n    {\n        $scans.Add(@{Function = 'Get-LogonSession -ReturnHashtables'; RoutingKey = 'siem'; ScanType = 'LogonSession'})\n    }\n    if($ScanType -contains 'All' -or $ScanType -contains 'MasterBootRecord')\n    {\n        $scans.Add(@{Function = 'Get-MasterBootRecord -ReturnHashtables'; RoutingKey = 'siem'; ScanType = 'MasterBootRecord'})\n    }\n    if($ScanType -contains 'All' -or $ScanType -contains 'NetworkConnection')\n    {\n        $scans.Add(@{Function = 'Get-NetworkConnection -ReturnHashtables'; RoutingKey = 'siem'; ScanType = 'NetworkConnection'})\n    }\n    if($ScanType -contains 'All' -or $ScanType -contains 'RegistryAutoRun')\n    {\n        $scans.Add(@{Function = 'Get-RegistryAutoRun'; RoutingKey = 'siem'; ScanType = 'RegistryAutoRun'})\n    }\n    if($ScanType -contains 'All' -or $ScanType -contains 'ScheduledTask')\n    {    \n        $scans.Add(@{Function = 'Get-PSIScheduledTask -ReturnHashtables'; RoutingKey = 'siem'; ScanType = 'ScheduledTask'})\n    }\n    if($ScanType -contains 'All' -or $ScanType -contains 'SecurityPackage')\n    {\n        $scans.Add(@{Function = 'Get-SecurityPackage -ReturnHashtables'; RoutingKey = 'siem'; ScanType = 'SecurityPackage'})\n    }\n    if($ScanType -contains 'All' -or $ScanType -contains 'SimpleNamedPipe')\n    {\n        $scans.Add(@{Function = 'Get-SimpleNamedPipe -ReturnHashtables'; RoutingKey = 'siem'; ScanType = 'SimpleNamedPipe'})\n    }\n    if($ScanType -contains 'All' -or $ScanType -contains 'WmiEventSubscription')\n    {\n        $scans.Add(@{Function = 'Get-WmiEventSubscription -ReturnHashtables'; RoutingKey = 'siem'; ScanType = 'WmiEventSubscription'})\n    }\n\n    foreach($scan in $scans)\n    {\n        $dataList = New-Object -TypeName System.Collections.Generic.List['string']\n\n        Write-Host -NoNewline -ForegroundColor Yellow -Object '[!] '\n        Write-Host \"[$($HostFQDN)] $($scan.ScanType)\"\n\n        foreach($o in (Invoke-Expression $scan.Function))\n        {\n            $o.Add('ComputerName', $HostFQDN)\n            $o.Add('ScanType', $scan.ScanType)\n            $o.Add('SweepId', $SweepId)\n            $o.Add('ScanId', $ScanId)\n            $o.Add('ResultDate', $ResultDate)\n\n            $message = ConvertTo-JsonV2 -InputObject $o\n            $dataList.Add($message)\n        }\n\n        $props = @{\n            ComputerName = $HostFQDN\n            ScanType     = $scan.ScanType\n            RoutingKey   = $scan.RoutingKey\n            ResultDate   = $ResultDate\n            ScanId       = $ScanId\n            Data         = $dataList.ToArray()\n        }\n\n        $body = (ConvertTo-JsonV2 -InputObject $props)\n        \n        #Write-Output $body\n        Invoke-AceWebRequest -Thumbprint $Thumbprint -Uri \"$($Uri)/ace/result/$($SweepId)\" -Body $body\n    }\n}\n\nfunction ConvertTo-JsonV2 \n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        $InputObject\n    )\n\n    Begin \n    {\n        $null = [System.Reflection.Assembly]::LoadWithPartialName(\"System.Web.Extensions\")\n        $Serializer = New-Object System.Web.Script.Serialization.JavaScriptSerializer\n    }\n\n    Process \n    {\n        try \n        {\n            $Serializer.Serialize($InputObject)\n        } \n        catch \n        {\n            Write-Error $_\n        }    \n    }\n}\n\nfunction Invoke-AceWebRequest\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Thumbprint,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Body\n    )\n\n    [Net.ServicePointManager]::ServerCertificateValidationCallback = {\n        $Thumbprint = $Thumbprint\n        $certificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]$args[1]\n    \n        if ($certificate -eq $null)\n        {\n            $Host.UI.WriteErrorLine(\"Null certificate.\")\n            return $true\n        }\n    \n        if ($certificate.Thumbprint -eq $Thumbprint)\n        {\n            return $true\n        }\n        else\n        {\n            $Host.UI.WriteErrorLine(\"Thumbprint mismatch. Certificate thumbprint $($certificate.Thumbprint)\")\n        }\n    \n        return $false\n    }\n\n    try\n    {\n        #Write-Host \"URI: $($Uri)\"\n\n        # Create web request\n        $WebRequest = [Net.WebRequest]::Create($uri)\n        $WebRequest.Method = 'Post'\n        $WebRequest.ContentType = 'application/json'\n        $WebRequest.Headers.Add('X-API-Version:1.0')\n\n        $byteArray = [System.Text.Encoding]::UTF8.GetBytes($Body)\n        $Webrequest.ContentLength = $byteArray.Length\n        \n        $dataStream = $Webrequest.GetRequestStream()            \n        $dataStream.Write($byteArray, 0, $byteArray.Length)\n        $dataStream.Close()\n\n        # Get response stream\n        $ResponseStream = $Webrequest.GetResponse().GetResponseStream()\n    \n        # Create a stream reader and read the stream returning the string value.\n        $StreamReader = New-Object System.IO.StreamReader -ArgumentList $ResponseStream\n        $StreamReader.ReadToEnd()\n    }\n    catch\n    {\n        Write-Error \"Failed: $($_.exception.innerexception.message)\"\n    }\n}\n\n#region Collection Functions\nfunction Get-AccessToken\n{\n    param\n    (\n        [Parameter()]\n        [System.Diagnostics.Process[]]\n        $Process\n    )\n\n    begin\n    {\n        <#\n        try\n        {\n            Get-System\n        }\n        catch\n        {\n            Write-Error \"Unable to Impersonate NT AUTHORITY\\SYSTEM token\"\n        }\n        #>\n\n        if(-not ($PSBoundParameters.ContainsKey('Process')))\n        {\n            $Process = Get-Process\n        }\n    }\n\n    process\n    {\n        foreach($proc in $Process)\n        {\n            if($proc.Id -ne 0 -and $proc.Id -ne 4 -and $proc.Id -ne $PID)\n            {\n                $ProcessGuid = [Guid]::NewGuid()\n\n                try\n                {\n                    $hProcess = OpenProcess -ProcessId $proc.Id -DesiredAccess PROCESS_QUERY_LIMITED_INFORMATION\n                }\n                catch\n                {\n                    if($_.Exception.Message -ne \"OpenProcess Error: The parameter is incorrect\")\n                    {\n                        Write-Warning \"Process Handle: $($proc.Id)\"\n                        Write-Warning $_.Exception.Message\n                    }\n                }\n\n                try\n                {\n                    $hToken = OpenProcessToken -ProcessHandle $hProcess -DesiredAccess TOKEN_QUERY\n                }\n                catch\n                {\n                    #Write-Warning \"Process Token Handle: $($proc.Id)\"\n                    #Write-Warning $_.Exception.Message\n                }\n\n                try\n                {\n                    $TokenUser = GetTokenInformation -TokenInformationClass TokenUser -TokenHandle $hToken\n                    $TokenGroup = GetTokenInformation -TokenInformationClass TokenGroups -TokenHandle $hToken\n                    $TokenOwner = GetTokenInformation -TokenInformationClass TokenOwner -TokenHandle $hToken\n                    $TokenIntegrityLevel = GetTokenInformation -TokenInformationClass TokenIntegrityLevel -TokenHandle $hToken\n                    $TokenType = GetTokenInformation -TokenInformationClass TokenType -TokenHandle $hToken\n                    $TokenSessionId = GetTokenInformation -TokenInformationClass TokenSessionId -TokenHandle $hToken\n                    $TokenOrigin = GetTokenInformation -TokenInformationClass TokenOrigin -TokenHandle $hToken\n                    $TokenPrivileges = (GetTokenInformation -TokenInformationClass TokenPrivileges -TokenHandle $hToken | Where-Object {$_.Attributes -like \"*ENABLED*\"} | select -ExpandProperty Privilege) -join \";\"\n                    $TokenElevation = GetTokenInformation -TokenInformationClass TokenElevation -TokenHandle $hToken\n                    $TokenElevationType = GetTokenInformation -TokenInformationClass TokenElevationType -TokenHandle $hToken\n\n                    $props = @{\n                        ProcessGuid = $ProcessGuid\n                        ProcessName = $proc.Name\n                        ProcessId = $proc.Id\n                        ThreadId = 0\n                        UserSid = $TokenUser.Sid.ToString()\n                        UserName = $TokenUser.Name.Value\n                        OwnerSid = $TokenOwner.Sid.ToString()\n                        OwnerName = $TokenOwner.Name.Value\n                        #Groups = $TokenGroup\n                        IntegrityLevel = $TokenIntegrityLevel.ToString()\n                        Type = $TokenType.ToString()\n                        ImpersonationLevel = 'None'\n                        SessionId = $TokenSessionId -as ([Int32])\n                        Origin = $TokenOrigin -as ([Int32])\n                        Privileges = $TokenPrivileges\n                        IsElevated = $TokenElevation -as ([bool])\n                        ElevationType = $TokenElevationType.ToString()\n                    }\n\n                    Write-Output $props\n\n                    CloseHandle -Handle $hProcess\n                    CloseHandle -Handle $hToken\n                }\n                catch\n                {\n                    #Write-Warning \"Process Token Query: $($proc.Id)\"\n                    #Write-Warning $_.Exception.Message\n                }\n\n                foreach($thread in $proc.Threads)\n                {\n                    try\n                    {\n                        $hThread = OpenThread -ThreadId $thread.Id -DesiredAccess THREAD_QUERY_LIMITED_INFORMATION\n\n                        try\n                        {\n                            $hToken = OpenThreadToken -ThreadHandle $hThread -DesiredAccess TOKEN_QUERY\n\n                            $TokenUser = GetTokenInformation -TokenInformationClass TokenUser -TokenHandle $hToken\n                            $TokenGroup = GetTokenInformation -TokenInformationClass TokenGroups -TokenHandle $hToken\n                            $TokenOwner = GetTokenInformation -TokenInformationClass TokenOwner -TokenHandle $hToken\n                            $TokenIntegrityLevel = GetTokenInformation -TokenInformationClass TokenIntegrityLevel -TokenHandle $hToken\n                            $TokenType = GetTokenInformation -TokenInformationClass TokenType -TokenHandle $hToken\n                            if($TokenType -eq 'TokenImpersonation')\n                            {\n                                $TokenImpersonationLevel = GetTokenInformation -TokenInformationClass TokenImpersonationLevel -TokenHandle $hToken\n                            }\n                            else\n                            {\n                                $TokenImpersonationLevel = 'None'\n                            }\n                            $TokenSessionId = GetTokenInformation -TokenInformationClass TokenSessionId -TokenHandle $hToken\n                            $TokenOrigin = GetTokenInformation -TokenInformationClass TokenOrigin -TokenHandle $hToken\n                            $TokenPrivileges = (GetTokenInformation -TokenInformationClass TokenPrivileges -TokenHandle $hToken | Where-Object {$_.Attributes -like \"*ENABLED*\"} | select -ExpandProperty Privilege) -join \";\"\n                            $TokenElevation = GetTokenInformation -TokenInformationClass TokenElevation -TokenHandle $hToken\n                            $TokenElevationType = GetTokenInformation -TokenInformationClass TokenElevationType -TokenHandle $hToken\n                        \n                            $props = @{\n                                ProcessGuid = $ProcessGuid\n                                ProcessName = $proc.Name\n                                ProcessId = $proc.Id\n                                ThreadId = $thread.Id\n                                UserSid = $TokenUser.Sid.ToString()\n                                UserName = $TokenUser.Name.Value\n                                OwnerSid = $TokenOwner.Sid.ToString()\n                                OwnerName = $TokenOwner.Name.Value\n                                #Groups = $TokenGroup\n                                IntegrityLevel = $TokenIntegrityLevel.ToString()\n                                Type = $TokenType.ToString()\n                                ImpersonationLevel = $TokenImpersonationLevel.ToString()\n                                SessionId = $TokenSessionId -as ([Int32])\n                                Origin = $TokenOrigin -as ([Int32])\n                                Privileges = $TokenPrivileges\n                                IsElevated = $TokenElevation -as ([bool])\n                                ElevationType = $TokenElevationType.ToString()\n                            }\n\n                            Write-Output $props    \n\n                            CloseHandle -Handle $hThread\n                            CloseHandle -Handle $hToken\n                        }\n                        catch\n                        {\n                            if($_.Exception.Message -ne 'OpenThreadToken Error: An attempt was made to reference a token that does not exist')\n                            {\n                                #Write-Warning \"Thread Token Handle\"\n                                #Write-Warning $_.Exception.Message\n                            }\n                        }\n                    }\n                    catch\n                    {\n                        #Write-Warning \"Thread Handle: [Proc] $($proc.Id) [THREAD] $($thread.Id)\"\n                        #Write-Warning $_.Exception.Message\n                    }\n                }\n            }\n        }\n    }\n\n    end\n    {\n        RevertToSelf\n    }\n}\n\nfunction Get-ArpCache\n{\n    <#\n    .SYNOPSIS\n\n    Gets the contents of the ARP Cache.\n\n    .DESCRIPTION\n    \n    The Get-ArpCache function retreives the contents of the system's ARP Cache. The ARP Cache contains cached mappings from IPv4 Addresses to their Physical Address (MAC Address).\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: None\n    Optional Dependencies: None\n\n    .EXAMPLE\n\n    Get-ArpCache\n\n    AdapterIndex       : 1\n    PhysicalAddress    : 00-00-00-00-00-00\n    IpAddress          : 224.0.0.22\n    Type               : STATIC\n    AdapterServiceName : e1iexpress\n    AdapterMacAddress  : 00:0C:29:3A:DF:39\n    AdapterType        : Ethernet 802.3\n    AdapterName        : Intel(R) 82574L Gigabit Network Connection\n    AdapterSpeed       : 1000000000\n\n    AdapterIndex       : 1\n    PhysicalAddress    : 00-00-00-00-00-00\n    IpAddress          : 224.0.0.252\n    Type               : STATIC\n    AdapterServiceName : e1iexpress\n    AdapterMacAddress  : 00:0C:29:3A:DF:39\n    AdapterType        : Ethernet 802.3\n    AdapterName        : Intel(R) 82574L Gigabit Network Connection\n    AdapterSpeed       : 1000000000\n\n    AdapterIndex       : 1\n    PhysicalAddress    : 00-00-00-00-00-00\n    IpAddress          : 239.255.255.250\n    Type               : STATIC\n    AdapterServiceName : e1iexpress\n    AdapterMacAddress  : 00:0C:29:3A:DF:39\n    AdapterType        : Ethernet 802.3\n    AdapterName        : Intel(R) 82574L Gigabit Network Connection\n    AdapterSpeed       : 1000000000\n    #>\n\n    param\n    (\n        [Parameter()]\n        [switch]\n        $ReturnHashtables\n    )\n\n    $Entries = GetIpNetTable\n    \n    foreach($Entry in $Entries)\n    {\n        $Adapter = Get-WmiObject -Class win32_networkadapter -Filter \"DeviceID = $($Entry.AdapterIndex)\"\n        \n        $Entry.Add('AdapterServiceName', $Adapter.ServiceName)\n        $Entry.Add('AdapterMacAddress', $Adapter.MACAddress)\n        $Entry.Add('AdapterType', $Adapter.AdapterType)\n        $Entry.Add('AdapterName', $Adapter.Name)\n        $Entry.Add('AdapterSpeed', $Adapter.Speed)\n        \n        if($ReturnHashtables)\n        {\n            Write-Output $Entry\n        }\n        else\n        {\n            New-Object -TypeName psobject -Property $Entry\n        }\n    }\n}\n\nfunction Get-AtomTable\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter()]\n        [UInt16]\n        $AtomIndex,\n\n        [Parameter()]\n        [switch]\n        $ReturnHashtables\n    )\n\n    if($PSBoundParameters.ContainsKey('AtomIndex'))\n    {\n        GlobalGetAtomName -AtomIndex $AtomIndex\n    }\n    else\n    {\n        $atomList = New-Object -TypeName System.Collections.Generic.List['string']\n\n        for($i = 0xC000; $i -lt [UInt16]::MaxValue; $i++)\n        {\n            try\n            {\n                $atomname = GlobalGetAtomName -AtomIndex $i -ErrorAction Stop\n            \n                $props = @{\n                    Index = $i\n                    Name = $atomname.ToString()\n                }\n\n                if($ReturnHashtables)\n                {\n                    Write-Output $props\n                }\n                else\n                {\n                    New-Object -TypeName psobject -Property $props\n                }\n            }\n            catch\n            {\n\n            }\n        }\n    }\n}\n\nfunction Get-InjectedThread\n{\n    <# \n    \n    .SYNOPSIS \n    \n    Looks for threads that were created as a result of code injection.\n    \n    .DESCRIPTION\n    \n    Memory resident malware (fileless malware) often uses a form of memory injection to get code execution. Get-InjectedThread looks at each running thread to determine if it is the result of memory injection.\n    \n    Common memory injection techniques that *can* be caught using this method include:\n    - Classic Injection (OpenProcess, VirtualAllocEx, WriteProcessMemory, CreateRemoteThread)\n    - Reflective DLL Injection\n    - Process Hollowing\n\n    NOTE: Nothing in security is a silver bullet. An attacker could modify their tactics to avoid detection using this methodology.\n    \n    .NOTES\n\n    Author - Jared Atkinson (@jaredcatkinson)\n\n    .EXAMPLE \n    \n    PS > Get-InjectedThread \n\n    ProcessName               : ThreadStart.exe\n    ProcessId                 : 7784\n    Path                      : C:\\Users\\tester\\Desktop\\ThreadStart.exe\n    KernelPath                : C:\\Users\\tester\\Desktop\\ThreadStart.exe\n    CommandLine               : \"C:\\Users\\tester\\Desktop\\ThreadStart.exe\"\n    PathMismatch              : False\n    ThreadId                  : 14512\n    AllocatedMemoryProtection : PAGE_EXECUTE_READWRITE\n    MemoryProtection          : PAGE_EXECUTE_READWRITE\n    MemoryState               : MEM_COMMIT\n    MemoryType                : MEM_PRIVATE\n    BasePriority              : 8\n    IsUniqueThreadToken       : False\n    Integrity                 : MEDIUM_MANDATORY_LEVEL\n    Privilege                 : SeChangeNotifyPrivilege\n    LogonId                   : 999\n    SecurityIdentifier        : S-1-5-21-386661145-2656271985-3844047388-1001\n    UserName                  : DESKTOP-HMTGQ0R\\SYSTEM\n    LogonSessionStartTime     : 3/15/2017 5:45:38 PM\n    LogonType                 : System\n    AuthenticationPackage     : NTLM\n    BaseAddress               : 4390912\n    Size                      : 4096\n    Bytes                     : {144, 195, 0, 0...}\n    \n    #>\n\n    [CmdletBinding()]\n    param\n    (\n\n    )\n\n    $hSnapshot = CreateToolhelp32Snapshot -ProcessId 0 -Flags 4\n\n    $Thread = Thread32First -SnapshotHandle $hSnapshot\n    \n    do\n    {\n        $proc = Get-Process -Id $Thread.th32OwnerProcessId -ErrorAction SilentlyContinue\n        \n        if($Thread.th32OwnerProcessId -ne 0 -and $Thread.th32OwnerProcessId -ne 4)\n        {       \n            try\n            {\n                $hThread = OpenThread -ThreadId $Thread.th32ThreadID -DesiredAccess THREAD_QUERY_INFORMATION\n            \n                if($hThread -ne 0)\n                {\n                    $BaseAddress = NtQueryInformationThread -ThreadHandle $hThread -ThreadInformationClass ThreadQuerySetWin32StartAddress\n                    $hProcess = OpenProcess -ProcessId $Thread.th32OwnerProcessID -DesiredAccess PROCESS_QUERY_LIMITED_INFORMATION -InheritHandle $false\n                \n                    if($hProcess -ne 0)\n                    {\n                        $memory_basic_info = VirtualQueryEx -ProcessHandle $hProcess -BaseAddress $BaseAddress\n                        $AllocatedMemoryProtection = $memory_basic_info.AllocationProtect -as $MEMORY_PROTECTION\n                        $MemoryProtection = $memory_basic_info.Protect -as $MEMORY_PROTECTION\n                        $MemoryState = $memory_basic_info.State -as $MEMORY_STATE\n                        $MemoryType = $memory_basic_info.Type -as $MEMORY_TYPE\n\n                        if($MemoryState -eq $MEMORY_STATE::MEM_COMMIT -and $MemoryType -ne $MEMORY_TYPE::MEM_IMAGE)\n                        {   \n                            $buf = ReadProcessMemory -ProcessHandle $hProcess -BaseAddress $BaseAddress -Size 100\n                            $proc = Get-WmiObject Win32_Process -Filter \"ProcessId = '$($Thread.th32OwnerProcessID)'\"\n                            $KernelPath = QueryFullProcessImageName -ProcessHandle $hProcess\n                            $PathMismatch = $proc.Path.ToLower() -ne $KernelPath.ToLower()\n                            \n                            # check if thread has unique token\n                            try\n                            {\n                                $hThreadToken = OpenThreadToken -ThreadHandle $hThread -DesiredAccess TOKEN_QUERY\n                                \n                                $TokenUser = GetTokenInformation -TokenInformationClass TokenUser -TokenHandle $hThreadToken\n                                $TokenOwner = GetTokenInformation -TokenInformationClass TokenOwner -TokenHandle $hThreadToken\n                                $TokenIntegrityLevel = GetTokenInformation -TokenInformationClass TokenIntegrityLevel -TokenHandle $hThreadToken\n                                $TokenType = GetTokenInformation -TokenInformationClass TokenType -TokenHandle $hThreadToken\n                                if($TokenType -eq 'TokenImpersonation')\n                                {\n                                    $TokenImpersonationLevel = GetTokenInformation -TokenInformationClass TokenImpersonationLevel -TokenHandle $hThreadToken\n                                }\n                                else\n                                {\n                                    $TokenImpersonationLevel = 'None'\n                                }\n                                $TokenSessionId = GetTokenInformation -TokenInformationClass TokenSessionId -TokenHandle $hThreadToken\n                                $TokenOrigin = GetTokenInformation -TokenInformationClass TokenOrigin -TokenHandle $hThreadToken\n                                $TokenPrivileges = (GetTokenInformation -TokenInformationClass TokenPrivileges -TokenHandle $hThreadToken | Where-Object {$_.Attributes -like \"*ENABLED*\"} | select -ExpandProperty Privilege) -join \";\"\n                                $TokenElevation = GetTokenInformation -TokenInformationClass TokenElevation -TokenHandle $hThreadToken\n                                $TokenElevationType = GetTokenInformation -TokenInformationClass TokenElevationType -TokenHandle $hThreadToken\n                            }\n                            catch\n                            {\n                                $hProcessToken = OpenProcessToken -ProcessHandle $hProcess -DesiredAccess TOKEN_QUERY\n                                \n                                $TokenUser = GetTokenInformation -TokenInformationClass TokenUser -TokenHandle $hProcessToken\n                                $TokenOwner = GetTokenInformation -TokenInformationClass TokenOwner -TokenHandle $hProcessToken\n                                $TokenIntegrityLevel = GetTokenInformation -TokenInformationClass TokenIntegrityLevel -TokenHandle $hProcessToken\n                                $TokenType = GetTokenInformation -TokenInformationClass TokenType -TokenHandle $hProcessToken\n                                $TokenImpersonationLevel = 'None'\n                                $TokenSessionId = GetTokenInformation -TokenInformationClass TokenSessionId -TokenHandle $hProcessToken\n                                $TokenOrigin = GetTokenInformation -TokenInformationClass TokenOrigin -TokenHandle $hProcessToken\n                                $TokenPrivileges = (GetTokenInformation -TokenInformationClass TokenPrivileges -TokenHandle $hProcessToken | Where-Object {$_.Attributes -like \"*ENABLED*\"} | select -ExpandProperty Privilege) -join \";\"\n                                $TokenElevation = GetTokenInformation -TokenInformationClass TokenElevation -TokenHandle $hProcessToken\n                                $TokenElevationType = GetTokenInformation -TokenInformationClass TokenElevationType -TokenHandle $hProcessToken\n                            }\n\n                            $props = @{\n                                ProcessName = [string]$proc.Name\n                                ProcessId = $proc.ProcessId\n                                Path = [string]$proc.Path\n                                KernelPath = [string]$KernelPath\n                                CommandLine = [string]$proc.CommandLine\n                                PathMismatch = [string]$PathMismatch\n                                ThreadId = $Thread.th32ThreadId\n                                AllocatedMemoryProtection = [string]$AllocatedMemoryProtection\n                                MemoryProtection = [string]$MemoryProtection\n                                MemoryState = [string]$MemoryState\n                                MemoryType = [string]$MemoryType\n                                BasePriority = $Thread.tpBasePri\n                                BaseAddress = [string]$BaseAddress\n                                Size = $memory_basic_info.RegionSize\n                                TokenUserSid = $TokenUser.Sid.ToString()\n                                TokenUserName = $TokenUser.Name.Value\n                                TokenOwnerSid = $TokenOwner.Sid.ToString()\n                                TokenOwnerName = $TokenOwner.Name.Value\n                                TokenIntegrity = $TokenIntegrityLevel.ToString()\n                                TokenType = $TokenType.ToString()\n                                TokenImpersonationLevel = $TokenImpersonationLevel.ToString()\n                                TokenSessionId = $TokenSessionId -as ([Int32])\n                                TokenOrigin = $TokenOrigin -as ([Int32])\n                                TokenPrivilege = $TokenPrivileges\n                                TokenElevation = $TokenElevation -as ([bool])\n                                TokenElevationType = $TokenElevationType.ToString()\n                            }\n                        \n                            Write-Output $props\n                        }\n                        CloseHandle($hProcess)\n                    }\n                }\n                CloseHandle($hThread)\n            }\n            catch\n            {\n\n            }\n        }\n    } while($Kernel32::Thread32Next($hSnapshot, [ref]$Thread))\n    CloseHandle($hSnapshot)\n}\n\nfunction Get-KerberosTicketCache\n{\n    <#\n    .SYNOPSIS\n\n    \n    .DESCRIPTION\n\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: None\n    Optional Dependencies: None\n\n    .EXAMPLE\n    \n    #>\n    \n    [CmdletBinding()]\n    param\n    (\n\n    )\n    \n    try\n    {\n        # We need a Handle to LSA to list Kerberos tickets\n        # If we want to look at tickets from a session other than our own\n        # Then we need to use LsaRegisterLogonProcess instead of LsaConnectUntrusted\n        $hLsa = LsaRegisterLogonProcess\n    }\n    catch\n    {\n        # If the original call fails then it is likely we don't have SeTcbPrivilege\n        # To get SeTcbPrivilege we can Impersonate a NT AUTHORITY\\SYSTEM Token\n        Get-System\n            \n        # We should now have the proper privileges to get a Handle to LSA\n        $hLsa = LsaRegisterLogonProcess\n\n        # We don't need our NT AUTHORITY\\SYSTEM Token anymore\n        # So we can revert to our original token\n        RevertToSelf\n    }\n\n    # Enumerate all Logon Sessions\n    # We need the sessions' LogonIds to enumerate it\n    $Sessions = Get-LogonSession\n\n    foreach($Session in $Sessions)\n    {\n        try\n        {\n            # Get the tickets from the LSA provider\n            $ticket = LsaCallAuthenticationPackage -LsaHandle $hLsa -AuthenticationPackageName MICROSOFT_KERBEROS_NAME_A -LogonId $Session.LogonId \n            \n            if($ticket -ne $null)\n            {\n                # Add properties from the Logon Session to the ticket\n                foreach($t in $ticket)\n                {\n                    $t.Add('SessionLogonId', $Session.LogonId)\n                    $t.Add('SessionUserName', $Session.UserName)\n                    $t.Add('SessionLogonDomain', $Session.LogonDomain)\n                    $t.Add('SessionAuthenticationPackage', $Session.AuthenticationPackage)\n                    $t.Add('SessionSid', $Session.Sid.ToString())\n                    $t.Add('SessionLogonType', $Session.LogonType)\n                    $t.Add('SessionUserPrincipalName', $Session.Upn)\n                }\n\n\n                # Output the ticket\n                Write-Output $ticket\n            }\n        }\n        catch\n        {\n\n        }\n    }\n\n    # Cleanup our LSA Handle\n    LsaDeregisterLogonProcess -LsaHandle $hLsa\n}\n\nfunction Get-LogonSession\n{\n    <#\n\n    .SYNOPSIS\n\n    .DESCRIPTION\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: \n    Required Dependencies: PSReflect, LsaEnumerateLogonSessions (Function), LsaFreeReturnBuffer (Function), LsaGetLogonSessionData (Function) LsaNtStatusToWinError (Function), SECURITY_LOGON_SESSION_DATA (Structure), LUID (Structure), LSA_UNICODE_STRING (Structure), LSA_LAST_INTER_LOGON_INFO (Structure), SecurityEntity (Enumeration), SECURITY_LOGON_TYPE (Enumeration)\n    Optional Dependencies: None\n\n    .LINK\n\n    .EXAMPLE\n\n    Get-LogonSession\n\n    FailedAttemptCountSinceLastSuccessfulLogon : 0\n    DnsDomainName                              : HUNT.LOCAL\n    KickOffTime                                : 1/1/1601 1:00:00 AM\n    PasswordCanChange                          : 5/20/2017 9:51:20 PM\n    Upn                                        : Administrator@HUNT.LOCAL\n    UserName                                   : Administrator\n    Session                                    : 1\n    LogoffTime                                 : 1/1/1601 1:00:00 AM\n    LastFailedLogon                            : 1/1/1601 1:00:00 AM\n    LogonServer                                : DC\n    Sid                                        : S-1-5-21-3250051078-751264820-3215766868-500\n    LogonScript                                : \n    UserFlags                                  : 49444\n    ProfilePath                                : \n    PasswordMustChange                         : 6/30/2017 9:51:20 PM\n    LogonId                                    : 325349\n    LogonTime                                  : 5/20/2017 9:47:34 AM\n    PasswordLastSet                            : 5/19/2017 9:51:20 PM\n    LogonDomain                                : \n    HomeDirectory                              : \n    LogonType                                  : Interactive\n    AuthenticationPackage                      : Kerberos\n    LastSuccessfulLogon                        : 1/1/1601 1:00:00 AM\n    HomeDirectoryDrive                         : \n\n    #>\n\n    [CmdletBinding()]\n    param\n    (\n        [Parameter()]\n        [switch]\n        $ReturnHashtables\n    )\n\n    $LogonSessions = LsaEnumerateLogonSessions\n\n    try\n    {\n        $Sessions = LsaGetLogonSessionData -LuidPtr $LogonSessions.SessionListPointer -SessionCount $LogonSessions.SessionCount\n    }\n    catch\n    {\n        \n    }\n\n    if($ReturnHashtables)\n    {\n        Write-Output $Sessions\n    }\n    else\n    {\n        foreach($session in $Sessions)\n        {\n            New-Object -TypeName psobject -Property $session\n        }\n    }\n}\n\nfunction Get-MasterBootRecord\n{\n<#\n    .SYNOPSIS\n\n        Returns detailed information about the master boot record\n\n        Author: Jared Atkinson\n        License: BSD 3-Clause\n        Required Dependencies: None\n        Optional Dependencies: None\n\n#>\n    [CmdletBinding()]\n    Param\n    (\n        [Parameter()]\n        [String[]]\n        $Path,\n\n        [switch]\n        $ReturnHashtables\n    )\n    \n    begin\n    {\n        function Get-FileHandle\n        {\n            [CmdletBinding()]\n            param\n            (\n                [Parameter(Mandatory = $true)]\n                [string]\n                $Path\n            )\n            \n            #region Constants\n        \n            $GENERIC_READWRITE = 0x80000000\n            $FILE_SHARE_READWRITE = 0x02 -bor 0x01\n            $OPEN_EXISTING = 0x03\n        \n            #endregion\n\n            #region Reflection\n            $DynAssembly = New-Object System.Reflection.AssemblyName('Win32')\n            $AssemblyBuilder = [AppDomain]::CurrentDomain.DefineDynamicAssembly($DynAssembly, [Reflection.Emit.AssemblyBuilderAccess]::Run)\n            $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('Win32', $False)\n\n            $TypeBuilder = $ModuleBuilder.DefineType('Win32.Kernel32', 'Public, Class')\n            $DllImportConstructor = [Runtime.InteropServices.DllImportAttribute].GetConstructor(@([String]))\n            $SetLastError = [Runtime.InteropServices.DllImportAttribute].GetField('SetLastError')\n            $SetLastErrorCustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($DllImportConstructor,\n                @('kernel32.dll'),\n                [Reflection.FieldInfo[]]@($SetLastError),\n                @($True))\n\n            # Define [Win32.Kernel32]::CreateFile\n            $PInvokeMethod = $TypeBuilder.DefinePInvokeMethod('CreateFile',\n                'kernel32.dll',\n                ([Reflection.MethodAttributes]::Public -bor [Reflection.MethodAttributes]::Static),\n                [Reflection.CallingConventions]::Standard,\n                [Microsoft.Win32.SafeHandles.SafeFileHandle],\n                [Type[]]@([String], [Int32], [UInt32], [IntPtr], [UInt32], [UInt32], [IntPtr]),\n                [Runtime.InteropServices.CallingConvention]::Winapi,\n                [Runtime.InteropServices.CharSet]::Ansi)\n            $PInvokeMethod.SetCustomAttribute($SetLastErrorCustomAttribute)\n\n            $Kernel32 = $TypeBuilder.CreateType()\n            #endregion\n\n            # Get handle to $FileToServe\n            $DriveHandle = $Kernel32::CreateFile($Path, $GENERIC_READWRITE, $FILE_SHARE_READWRITE, 0, $OPEN_EXISTING, 0, 0)\n\n            # Check that handle is valid\n            if ($DriveHandle.IsInvalid) {\n                Write-Error \"Invalid handle to $($Path) returned from CreateFile\" -ErrorAction Stop\n            }\n            else {\n                $DriveHandle\n            }\n        }\n               \n        function Read-MbrBytes\n        {\n            [CmdletBinding()]\n            param\n            (\n                [Parameter(Mandatory = $true)]\n                [Microsoft.Win32.SafeHandles.SafeFileHandle]\n                $Handle\n            )\n\n            try\n            {\n                # Create a FileStream to read from the handle\n                $streamToRead = New-Object -TypeName System.IO.FileStream($Handle, [System.IO.FileAccess]::Read)\n            \n                # Set our position in the stream to $Offset\n                $streamToRead.Position = 0x0\n        \n                # Create a buffer $Length bytes long\n                $buffer = New-Object -TypeName Byte[](0x200)\n\n                # Read $Length bytes\n                $return = $streamToRead.Read($buffer, 0x0, 0x200)\n            \n                # Check return value\n                if($return -ne 0x200)\n                {\n                    $return\n                }\n\n                $buffer\n            }\n            catch\n            {\n                Write-Error \"Unable to read bytes from Drive\" -ErrorAction Stop\n            }\n            finally\n            {\n                $streamToRead.Dispose()\n            }\n        }\n        \n        function Get-MD5Hash\n        {\n            param\n            (\n                [Parameter(Mandatory = $true)]\n                [byte[]]\n                $Bytes\n            )\n            \n            begin\n            {\n                $sha1 = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider\n                $hashbytes = $sha1.ComputeHash($Bytes)\n                $sb = New-Object -TypeName System.Text.StringBuilder\n            }\n\n            process\n            {\n                foreach($b in $hashbytes)\n                {\n                    $null = $sb.Append(\"{0:x}\" -f $b)\n                }\n\n                $sb.ToString()\n            }\n\n            end\n            {\n                if($sha1.Dispose) {\n                    $sha1.Dispose()\n                }\n            }\n        }\n\n        function Get-Partition\n        {\n            param\n            (\n                [Parameter(Mandatory = $true)]\n                [byte[]]\n                $Bytes,\n\n                [Parameter(Mandatory = $true)]\n                [int]\n                $Offset,\n\n                [switch]\n                $ReturnHashtables\n            )\n\n            # Status (0x00 - Non-Bootable & 0x80 - Bootable)\n            if($Bytes[0x00 + $Offset] -eq 0x80)\n            {\n                $Bootable = $true\n            }\n            else\n            {\n                $Bootable = $false\n            }\n\n            $props = @{\n                Bootable = $Bootable\n                PartitionType = $Bytes[0x04 + $Offset]\n                RelativeStartSector = [System.BitConverter]::ToUInt32($Bytes, 0x08 + $Offset)\n                TotalSectors = [System.BitConverter]::ToUInt32($Bytes, 0x0C + $Offset)\n            }\n\n            if($ReturnHashtables) {\n                $props\n            } else {\n                New-Object -TypeName psobject -Property $props\n            }\n        }\n    }\n\n    process\n    {\n        if(-not($PSBoundParameters.ContainsKey('Path')))\n        {\n            $Disks = Get-WmiObject -Query \"SELECT * FROM Win32_DiskDrive\"\n        }\n        else\n        {\n\n        }\n\n        $OS = (Get-WmiObject win32_Operatingsystem).Caption\n\n        foreach($disk in $Disks)\n        {\n            $hDrive = Get-FileHandle -Path $disk.DeviceId\n\n            if($hDrive) {\n                $bytes = Read-MbrBytes -Handle $hDrive\n\n                $CodeSection = $bytes[0x3E..0x1B7]\n\n                $listPartitions = New-Object -TypeName System.Collections.Generic.List[HashTable]\n\n                for($i = 0; $i -lt 4; $i++)\n                {\n                    if($ReturnHashtables) {\n                        $partition = Get-Partition -Bytes $bytes -Offset (0x1BE + (0x10 * $i)) -ReturnHashtables\n                    } else {\n                        $partition = Get-Partition -Bytes $bytes -Offset (0x1BE + (0x10 * $i))\n                    }\n\n                    if($partition.TotalSectors -ne 0)\n                    {\n                        $listPartitions.Add($partition)\n                    }\n                }\n\n                $Props = @{\n                    OperatingSystem = $OS\n                    DeviceId = $disk.DeviceId\n                    Model = $disk.Model\n                    Signature = Get-MD5Hash -Bytes $CodeSection\n                    CodeSection = $CodeSection\n                    DiskSignature = [System.BitConverter]::ToString($bytes[0x1B8..0x1BB]).Replace(\"-\", \"\")\n                    PartitionTable = $listPartitions.ToArray()\n                }\n\n                if($ReturnHashtables) {\n                    $Props\n                } else {\n                    New-Object -TypeName psobject -Property $Props\n                }\n            }\n        }\n    }\n}\n\nfunction Get-NetworkConnection \n{\n    <#\n    .SYNOPSIS\n\n    Returns current TCP and UDP connections.\n\n    .NOTES\n\n    Author: Lee Christensen (@tifkin_)\n    License: BSD 3-Clause\n    Required Dependencies: None\n    Optional Dependencies: None\n    #>\n    [CmdletBinding()]\n    param \n    (\n        [switch]\n        $ResolveHostnames,\n\n        [switch]\n        $ReturnHashtables\n    )\n\n    $Tcp4Connections = Get-Tcp4Connections @PSBoundParameters\n    $Tcp6Connections = Get-Tcp6Connections @PSBoundParameters\n    $Udp4Connections = Get-Udp4Connections @PSBoundParameters\n    $Udp6Connections = Get-Udp6Connections @PSBoundParameters\n\n    $Tcp4Connections\n    $Tcp6Connections\n    $Udp4Connections\n    $Udp6Connections\n}\n\nfunction Get-PSIProcess\n{\n<#\n    .SYNOPSIS\n\n        Returns detailed information about the current running processes.\n\n        Author: Lee Christensen (@tifkin_)\n        License: BSD 3-Clause\n        Required Dependencies: None\n        Optional Dependencies: None\n\n#>\n    [CmdletBinding()]\n    Param (\n        [switch]\n        $ReturnHashtables\n    )\n\n    # TODO: Optimize this cmdlet...\n\n    begin\n    {\n        # Thanks to https://p0w3rsh3ll.wordpress.com/2015/02/05/backporting-the-get-filehash-function/\n        function Get-DIGSFileHash\n        {\n            [CmdletBinding(DefaultParameterSetName = \"Path\")]\n            param\n            (\n                [Parameter(Mandatory=$true, ParameterSetName=\"Path\", Position = 0)]\n                [System.String[]]\n                $Path,\n\n                [Parameter(Mandatory=$true, ParameterSetName=\"LiteralPath\", ValueFromPipelineByPropertyName = $true)]\n                [Alias(\"PSPath\")]\n                [System.String[]]\n                $LiteralPath,\n        \n                [Parameter(Mandatory=$true, ParameterSetName=\"Stream\")]\n                [System.IO.Stream]\n                $InputStream,\n\n                [ValidateSet(\"SHA1\", \"SHA256\", \"SHA384\", \"SHA512\", \"MACTripleDES\", \"MD5\", \"RIPEMD160\")]\n                [System.String]\n                $Algorithm=\"SHA256\"\n            )\n    \n            begin\n            {\n                # Construct the strongly-typed crypto object\n                $hasher = [System.Security.Cryptography.HashAlgorithm]::Create($Algorithm)\n            }\n    \n            process\n            {\n                if($PSCmdlet.ParameterSetName -eq \"Stream\")\n                {\n                    Get-DIGSStreamHash -InputStream $InputStream -RelatedPath $null -Hasher $hasher\n                }\n                else\n                {\n                    $pathsToProcess = @()\n                    if($PSCmdlet.ParameterSetName  -eq \"LiteralPath\")\n                    {\n                        $pathsToProcess += Resolve-Path -LiteralPath $LiteralPath | Foreach-Object { $_.ProviderPath }\n                    }\n                    if($PSCmdlet.ParameterSetName -eq \"Path\")\n                    {\n                        $pathsToProcess += Resolve-Path $Path | Foreach-Object { $_.ProviderPath }\n                    }\n\n                    foreach($filePath in $pathsToProcess)\n                    {\n                        if(Test-Path -LiteralPath $filePath -PathType Container)\n                        {\n                            continue\n                        }\n\n                        try\n                        {\n                            # Read the file specified in $FilePath as a Byte array\n                            [system.io.stream]$stream = [system.io.file]::OpenRead($filePath)\n                            Get-DIGSStreamHash -InputStream $stream  -RelatedPath $filePath -Hasher $hasher\n                        }\n                        catch [Exception]\n                        {\n                            $errorMessage = 'FileReadError {0}:{1}' -f $FilePath, $_\n                            Write-Error -Message $errorMessage -Category ReadError -ErrorId \"FileReadError\" -TargetObject $FilePath\n                            return\n                        }\n                        finally\n                        {\n                            if($stream)\n                            {\n                                $stream.Close()\n                            }\n                        }                            \n                    }\n                }\n            }\n        }\n\n        function Get-DIGSStreamHash\n        {\n            param\n            (\n                [System.IO.Stream]\n                $InputStream,\n\n                [System.String]\n                $RelatedPath,\n\n                [System.Security.Cryptography.HashAlgorithm]\n                $Hasher\n            )\n\n            # Compute file-hash using the crypto object\n            [Byte[]] $computedHash = $Hasher.ComputeHash($InputStream)\n            [string] $hash = [BitConverter]::ToString($computedHash) -replace '-',''\n\n            if ($RelatedPath -eq $null)\n            {\n                $retVal = [PSCustomObject] @{\n                    Algorithm = $Algorithm.ToUpperInvariant()\n                    Hash = $hash\n                }\n                $retVal.psobject.TypeNames.Insert(0, \"Microsoft.Powershell.Utility.FileHash\")\n                $retVal\n            }\n            else\n            {\n                $retVal = [PSCustomObject] @{\n                    Algorithm = $Algorithm.ToUpperInvariant()\n                    Hash = $hash\n                    Path = $RelatedPath\n                }\n                $retVal.psobject.TypeNames.Insert(0, \"Microsoft.Powershell.Utility.FileHash\")\n                $retVal\n\n            }\n        }\n \n        $FileHashCache = @{}\n        $Processes = Get-WmiObject -Class Win32_Process\n\n        function Get-DIGSCachedFileHash\n        {\n            param\n            (\n                [string]\n                $File\n            )\n\n            if($FileHashCache[$File])\n            {\n                $FileHashCache[$File]\n            }\n            else\n            {\n                if($File -and (Test-Path $File))\n                {\n                    $ModuleMD5 = (Get-DIGSFileHash -Path $File -Algorithm MD5).Hash\n                    $ModuleSHA256 = (Get-DIGSFileHash -Path $File -Algorithm SHA256).Hash\n\n                    $FileHashCache[$File] = New-Object PSObject -Property @{\n                        MD5 = $ModuleMD5\n                        SHA256 = $ModuleSHA256\n                    }\n\n                    $FileHashCache[$File]\n                }\n            }\n        }\n    }\n\n    process\n    {\n        foreach($Process in $Processes)\n        {\n            $Proc = Get-Process -Id $Process.ProcessId -ErrorAction SilentlyContinue\n            $Path = $Proc.Path\n            $LoadedModules = $null\n            $Owner = $null\n            $OwnerStr = $null\n\n            if($Proc)\n            {\n                #$PE = Get-PE -ModuleBaseAddress $Proc.MainModule.BaseAddress -ProcessID $Process.ProcessId\n                $Proc.Modules | ForEach-Object {\n                    if($_) \n                    {\n                        $ModuleHash = Get-DIGSCachedFileHash -File $_.FileName\n\n                        $_ | Add-Member NoteProperty -Name \"MD5Hash\" -Value $ModuleHash.MD5\n                        $_ | Add-Member NoteProperty -Name \"SHA256Hash\" -Value $ModuleHash.SHA256\n                    }\n                }\n                $LoadedModules = $Proc.Modules\n            }\n\n            # Get file information\n            $FileHash = $null\n            if($Path -ne $null -and (Test-Path $Path)) {\n                # TODO: Add error handling here in case we can't read the file (wonky exe permissions)\n\n                $FileHash = Get-DIGSCachedFileHash -File $Path\n\n                $File = (Get-ChildItem $Path)\n                $FileSize = $File.Length\n                $FileCreationTime = $File.CreationTimeUtc\n                $FileLastAccessTime = $File.LastAccessTimeUtc\n                $FileLastWriteTime = $File.LastWriteTimeUtc\n                $FileExtension = $File.Extension\n                $ProcessId = $Process.ProcessId\n            } else {\n                if($Proc.Id -ne 0 -and $Proc.Id -ne 4)\n                {\n                    #Write-Warning \"Could not find executable path. PSProcessName: $($Proc.Name) PSPid: $($Proc.Id) WMIProcName: $($Process.Name) WMIPid: $($Process.ProcessId)\"\n                }\n                $Path = ''\n            }\n        \n            # Get the process owner\n            $NTVersion = [System.Environment]::OSVersion.Version\n            try {\n                if($NTVersion.Major -ge 6)\n                {\n                    $Owner = $Process.GetOwner()\n                    if($Owner -and ($Owner.Domain -or $Owner.User)) {\n                        $OwnerStr = \"$($Owner.Domain)\\$($Owner.User)\"\n                    }\n        \n                    $OwnerObj = $Process.GetOwnerSid()\n                    if($OwnerObj)\n                    {\n                        $OwnerSid = $OwnerObj.Sid\n                    }\n                }\n            } catch {}\n\n            $LoadedModuleList = $LoadedModules | sort ModuleName | select -ExpandProperty ModuleName\n            $ParentProcess = Get-Process -Id $Process.ProcessId -ErrorAction SilentlyContinue\n        \n            $ErrorActionPreference = 'Stop'\n            $Output = @{\n                Name = $Process.Name\n                Path = [string]$Process.Path\n                CommandLine = $Process.CommandLine\n                MD5Hash = $FileHash.MD5\n                SHA256Hash = $FileHash.SHA256\n                FileSize = $FileSize\n                FileCreationTime = $FileCreationTime\n                FileLastAccessTime = $FileLastAccessTime\n                FileLastWriteTime = $FileLastWriteTime\n                FileExtension = $FileExtension\n                Owner = $OwnerStr\n                OwnerSid = $OwnerSid\n                ParentProcessId = $Process.ParentProcessID\n                ParentProcessName = $ParentProcess.Name\n                ProcessId = $ProcessId\n                ## PE = $PE\n                #LoadedModules = $LoadedModules | select *\n                LoadedModulesList = ($LoadedModuleList -join \";\").ToLower()\n            }\n\n            try {\n                $null = ConvertTo-JsonV2 $Output\n            } catch {\n                Write-Error $_\n            }\n\n            if($ReturnHashtables) {\n                $Output\n            } else {\n                 New-Object PSObject -Property $Output\n            }\n        }\n    }\n\n    end\n    {\n\n    }\n}\n\nfunction Get-PSIScheduledTask \n{\n<#\n    .SYNOPSIS\n\n        Returns detailed information about scheduled tasks.\n\n        Author: Lee Christensen (@tifkin_), Jared Atkinson\n        License: BSD 3-Clause\n        Required Dependencies: None\n        Optional Dependencies: None\n\n#>\n    [CmdletBinding()]\n    Param (\n        [switch]\n        $ReturnHashtables\n    )\n\n    begin\n    {\n        # Based on Get-ScheduledTask in the Windows 7 Resource Kit PowerShell Pack\n        function Get-DIGSScheduledTaskData\n        {\n            <#\n            .Synopsis\n                Gets tasks scheduled on the computer\n            .Description\n                Gets scheduled tasks that are registered on a computer\n            .Example\n                Get-ScheduleTask -Recurse\n            #>\n            param(\n            # The name or name pattern of the scheduled task\n            [Parameter()]\n            $Name = \"*\",\n    \n            # The folder the scheduled task is in\n            [Parameter()]\n            [String[]]\n            $Folder = \"\",\n    \n            # If this is set, hidden tasks will also be shown.  \n            # By default, only tasks that are not marked by Task Scheduler as hidden are shown.\n            [Switch]\n            $Hidden,    \n    \n            # The name of the computer to connect to.\n            $ComputerName,\n    \n            # The credential used to connect\n            [Management.Automation.PSCredential]\n            $Credential,\n    \n            # If set, will get tasks recursively beneath the specified folder\n            [switch]\n            $Recurse\n            )\n    \n            process {\n                $scheduler = New-Object -ComObject Schedule.Service\n                if ($Credential) { \n                    $NetworkCredential = $Credential.GetNetworkCredential()\n                    $scheduler.Connect($ComputerName, \n                        $NetworkCredential.UserName, \n                        $NetworkCredential.Domain, \n                        $NetworkCredential.Password)            \n                } else {\n                    $scheduler.Connect($ComputerName)        \n                }    \n                \n                $taskFolder = $scheduler.GetFolder($folder)\n                $taskFolder.GetTasks($Hidden -as [bool]) | Where-Object {\n                    $_.Name -like $name\n                }\n                if ($Recurse) {\n                    $taskFolder.GetFolders(0) | ForEach-Object {\n                        $psBoundParameters.Folder = $_.Path\n                        Get-DIGSScheduledTaskData @psBoundParameters\n                    }\n                }        \n            }\n        }\n\n        # Thanks to https://p0w3rsh3ll.wordpress.com/2015/02/05/backporting-the-get-filehash-function/\n        function Get-DIGSFileHash\n        {\n\t        [CmdletBinding(DefaultParameterSetName = \"Path\")]\n\t        param(\n\t\t        [Parameter(Mandatory=$true, ParameterSetName=\"Path\", Position = 0)]\n\t\t        [System.String[]]\n\t\t        $Path,\n\n\t\t        [Parameter(Mandatory=$true, ParameterSetName=\"LiteralPath\", ValueFromPipelineByPropertyName = $true)]\n\t\t        [Alias(\"PSPath\")]\n\t\t        [System.String[]]\n\t\t        $LiteralPath,\n\t\n\t\t        [Parameter(Mandatory=$true, ParameterSetName=\"Stream\")]\n\t\t        [System.IO.Stream]\n\t\t        $InputStream,\n\n\t\t        [ValidateSet(\"SHA1\", \"SHA256\", \"SHA384\", \"SHA512\", \"MACTripleDES\", \"MD5\", \"RIPEMD160\")]\n\t\t        [System.String]\n\t\t        $Algorithm=\"SHA256\"\n\t        )\n\n\t        begin\n\t        {\n\t\t        # Construct the strongly-typed crypto object\n\t\t        $hasher = [System.Security.Cryptography.HashAlgorithm]::Create($Algorithm)\n\t        }\n\n\t        process\n\t        {\n\t\t        if($PSCmdlet.ParameterSetName -eq \"Stream\")\n\t\t        {\n\t\t\t        Get-DIGSStreamHash -InputStream $InputStream -RelatedPath $null -Hasher $hasher\n\t\t        }\n\t\t        else\n\t\t        {\n\t\t\t        $pathsToProcess = @()\n\t\t\t        if($PSCmdlet.ParameterSetName  -eq \"LiteralPath\")\n\t\t\t        {\n\t\t\t\t        $pathsToProcess += Resolve-Path -LiteralPath $LiteralPath | Foreach-Object { $_.ProviderPath }\n\t\t\t        }\n\t\t\t        if($PSCmdlet.ParameterSetName -eq \"Path\")\n\t\t\t        {\n\t\t\t\t        $pathsToProcess += Resolve-Path $Path | Foreach-Object { $_.ProviderPath }\n\t\t\t        }\n\n\t\t\t        foreach($filePath in $pathsToProcess)\n\t\t\t        {\n\t\t\t\t        if(Test-Path -LiteralPath $filePath -PathType Container)\n\t\t\t\t        {\n\t\t\t\t\t        continue\n\t\t\t\t        }\n\n\t\t\t\t        try\n\t\t\t\t        {\n\t\t\t\t\t        # Read the file specified in $FilePath as a Byte array\n\t\t\t\t\t        [system.io.stream]$stream = [system.io.file]::OpenRead($filePath)\n\t\t\t\t\t        Get-DIGSStreamHash -InputStream $stream  -RelatedPath $filePath -Hasher $hasher\n\t\t\t\t        }\n\t\t\t\t        catch [Exception]\n\t\t\t\t        {\n\t\t\t\t\t        $errorMessage = 'FileReadError {0}:{1}' -f $FilePath, $_\n\t\t\t\t\t        Write-Error -Message $errorMessage -Category ReadError -ErrorId \"FileReadError\" -TargetObject $FilePath\n\t\t\t\t\t        return\n\t\t\t\t        }\n\t\t\t\t        finally\n\t\t\t\t        {\n\t\t\t\t\t        if($stream)\n\t\t\t\t\t        {\n\t\t\t\t\t\t        $stream.Close()\n\t\t\t\t\t        }\n\t\t\t\t        }                            \n\t\t\t        }\n\t\t        }\n\t        }\n        }\n\n        function Get-DIGSStreamHash\n        {\n\t        param(\n\t\t        [System.IO.Stream]\n\t\t        $InputStream,\n\n\t\t        [System.String]\n\t\t        $RelatedPath,\n\n\t\t        [System.Security.Cryptography.HashAlgorithm]\n\t\t        $Hasher)\n\n\t        # Compute file-hash using the crypto object\n\t        [Byte[]] $computedHash = $Hasher.ComputeHash($InputStream)\n\t        [string] $hash = [BitConverter]::ToString($computedHash) -replace '-',''\n\n\t        if ($RelatedPath -eq $null)\n\t        {\n\t\t        $retVal = [PSCustomObject] @{\n\t\t\t        Algorithm = $Algorithm.ToUpperInvariant()\n\t\t\t        Hash = $hash\n\t\t        }\n\t\t        $retVal.psobject.TypeNames.Insert(0, \"Microsoft.Powershell.Utility.FileHash\")\n\t\t        $retVal\n\t        }\n\t        else\n\t        {\n\t\t        $retVal = [PSCustomObject] @{\n\t\t\t        Algorithm = $Algorithm.ToUpperInvariant()\n\t\t\t        Hash = $hash\n\t\t\t        Path = $RelatedPath\n\t\t        }\n\t\t        $retVal.psobject.TypeNames.Insert(0, \"Microsoft.Powershell.Utility.FileHash\")\n\t\t        $retVal\n\n\t        }\n        }\n\n        function Get-ClassID\n        {\n            param($ClassId)\n  \n            $Value = Get-ItemProperty \"HKLM:\\Software\\Classes\\CLSID\\$($ClassId)\\InprocServer32\" -Name \"(Default)\" -ErrorAction SilentlyContinue\n            if($Value) {\n                $Value.'(Default)'\n            } else {\n                ''\n            }\n        }  \n    }\n\n    process\n    {\n        $Tasks = Get-DIGSScheduledTaskData -Recurse\n\n        foreach($Task in $Tasks)\n        {\n            $ActionComClassId = $null\n            $ActionComDll = $null\n            $ActionComDllMD5 = $null\n            $ActionComDllSHA256 = $null\n            $ActionComData = $null\n            $ActionExecCommand = $null\n            $ActionExecCommandMD5 = $null\n            $ActionExecCommandSHA256 = $null\n            $ActionExecArguments = $null\n            $ActionExecWorkingDirectory = $null\n                \n            $Xml = [Xml]$Task.Xml\n    \n            $ActionCom = $Xml.Task.Actions.ComHandler\n            $ActionComDll = if($ActionCom.ClassId) { Get-ClassID ($ActionCom.ClassId)} else { $null }\n        \n            if($ActionComDll)\n            {\n                $ActionComDllMD5 =  (Get-DIGSFileHash -Path $ActionComDll -Algorithm MD5).Hash\n                $ActionComDllSHA256 = (Get-DIGSFileHash -Path $ActionComDll -Algorithm SHA256).Hash\n            }\n            $ActionComData = if($ActionCom.Data) { $ActionCom.Data.InnerXml} else {$null}\n\n            $ActionExec = $Xml.Task.Actions.Exec\n            if($ActionExec.Command)\n            {\n                $ActionExecPath = [System.Environment]::ExpandEnvironmentVariables($ActionExec.Command)\n            \n                $CleanedPath = $ActionExecPath.Replace(\"`\"\", \"\")\n                if(Test-Path $CleanedPath -ErrorAction SilentlyContinue)\n                {\n                    $ActionExecCommandMD5 = (Get-DIGSFileHash -Path $CleanedPath -Algorithm MD5).Hash\n                    $ActionExecCommandSHA256 = (Get-DIGSFileHash -Path $CleanedPath -Algorithm SHA256).Hash\n                }\n            }\n\n            $Output = @{\n                Name = $Task.Name\n                Path = $Task.Path\n                Enabled = $Task.Enabled\n                LastRunTime = $Task.LastRunTime\n                LastTaskResult = $Task.LastTaskResult\n                NumberOfMissedRuns = $Task.NumberOfMissedRuns\n                NextRunTime = $Task.NextRunTime\n                Xml = $Task.Xml\n                ActionComClassId = $ActionCom.ClassId\n                ActionComDll = $ActionComDll\n                ActionComDllMD5 = $ActionComDllMd5\n                ActionComDllSHA256 = $ActionComDllSHA256\n                ActionComData = $ActionComData\n                ActionExecCommand = $ActionExec.Command\n                ActionExecCommandMD5 = $ActionExecCommandMD5\n                ActionExecCommandSHA256 = $ActionExecCommandSHA256\n                ActionExecArguments = $ActionExec.Arguments\n                ActionExecWorkingDirectory = $ActionExec.WorkingDirectory\n            }\n\n            if($ReturnHashtables) {\n                $Output\n            } else {\n                New-Object PSObject -Property $Output\n            }\n        }\n    }\n\n    end\n    {\n\n    }\n}\n\nfunction Get-PSIService \n{\n<#\n    .SYNOPSIS\n\n        Returns detailed service information.\n\n        Author: Jared Atkinson\n        License: BSD 3-Clause\n        Required Dependencies: None\n        Optional Dependencies: None\n\n#>\n    [CmdletBinding()]\n    Param (\n        [switch]\n        $ReturnHashtables\n    )\n\n    Begin\n    {\n        function Get-PathFromCommandLine\n        {\n            Param\n            (\n                [Parameter(Mandatory = $true)]\n                [string]\n                $CommandLine\n            )\n\n            if(Test-Path -Path $CommandLine -ErrorAction SilentlyContinue)\n            {\n                $CommandLine\n            }\n            else\n            {\n                switch -Regex ($CommandLine)\n                {\n                    '\"\\s'{ $CommandLine.Split('\"')[1]; break}\n                    '\\s-'{ $CommandLine.Split(' ')[0]; break}\n                    '\\s/'{ $CommandLine.Split(' ')[0]; break}\n                    '\"'{ $CommandLine.Split('\"')[1]; break}\n                    default{ $CommandLine}    \n                }\n            }\n        }\n\n        # Thanks to https://p0w3rsh3ll.wordpress.com/2015/02/05/backporting-the-get-filehash-function/\n        function Get-DIGSFileHash\n        {\n            [CmdletBinding(DefaultParameterSetName = \"Path\")]\n            param(\n                [Parameter(Mandatory=$true, ParameterSetName=\"Path\", Position = 0)]\n                [System.String[]]\n                $Path,\n\n                [Parameter(Mandatory=$true, ParameterSetName=\"LiteralPath\", ValueFromPipelineByPropertyName = $true)]\n                [Alias(\"PSPath\")]\n                [System.String[]]\n                $LiteralPath,\n        \n                [Parameter(Mandatory=$true, ParameterSetName=\"Stream\")]\n                [System.IO.Stream]\n                $InputStream,\n\n                [ValidateSet(\"SHA1\", \"SHA256\", \"SHA384\", \"SHA512\", \"MACTripleDES\", \"MD5\", \"RIPEMD160\")]\n                [System.String]\n                $Algorithm=\"SHA256\"\n            )\n    \n            begin\n            {\n                # Construct the strongly-typed crypto object\n                $hasher = [System.Security.Cryptography.HashAlgorithm]::Create($Algorithm)\n            }\n    \n            process\n            {\n                if($PSCmdlet.ParameterSetName -eq \"Stream\")\n                {\n                    Get-DIGSStreamHash -InputStream $InputStream -RelatedPath $null -Hasher $hasher\n                }\n                else\n                {\n                    $pathsToProcess = @()\n                    if($PSCmdlet.ParameterSetName  -eq \"LiteralPath\")\n                    {\n                        $pathsToProcess += Resolve-Path -LiteralPath $LiteralPath | Foreach-Object { $_.ProviderPath }\n                    }\n                    if($PSCmdlet.ParameterSetName -eq \"Path\")\n                    {\n                        $pathsToProcess += Resolve-Path $Path | Foreach-Object { $_.ProviderPath }\n                    }\n\n                    foreach($filePath in $pathsToProcess)\n                    {\n                        if(Test-Path -LiteralPath $filePath -PathType Container)\n                        {\n                            continue\n                        }\n\n                        try\n                        {\n                            # Read the file specified in $FilePath as a Byte array\n                            [system.io.stream]$stream = [system.io.file]::OpenRead($filePath)\n                            Get-DIGSStreamHash -InputStream $stream  -RelatedPath $filePath -Hasher $hasher\n                        }\n                        catch [Exception]\n                        {\n                            $errorMessage = 'FileReadError {0}:{1}' -f $FilePath, $_\n                            Write-Error -Message $errorMessage -Category ReadError -ErrorId \"FileReadError\" -TargetObject $FilePath\n                            return\n                        }\n                        finally\n                        {\n                            if($stream)\n                            {\n                                $stream.Close()\n                            }\n                        }                            \n                    }\n                }\n            }\n        }\n\n        function Get-DIGSStreamHash\n        {\n            param(\n                [System.IO.Stream]\n                $InputStream,\n\n                [System.String]\n                $RelatedPath,\n\n                [System.Security.Cryptography.HashAlgorithm]\n                $Hasher)\n\n            # Compute file-hash using the crypto object\n            [Byte[]] $computedHash = $Hasher.ComputeHash($InputStream)\n            [string] $hash = [BitConverter]::ToString($computedHash) -replace '-',''\n\n            if ($RelatedPath -eq $null)\n            {\n                $retVal = [PSCustomObject] @{\n                    Algorithm = $Algorithm.ToUpperInvariant()\n                    Hash = $hash\n                }\n                $retVal.psobject.TypeNames.Insert(0, \"Microsoft.Powershell.Utility.FileHash\")\n                $retVal\n            }\n            else\n            {\n                $retVal = [PSCustomObject] @{\n                    Algorithm = $Algorithm.ToUpperInvariant()\n                    Hash = $hash\n                    Path = $RelatedPath\n                }\n                $retVal.psobject.TypeNames.Insert(0, \"Microsoft.Powershell.Utility.FileHash\")\n                $retVal\n\n            }\n        }\n    \n        $hashcache = @{}\n        $objList = New-Object -TypeName \"System.Collections.Generic.List[Object]\"\n    }\n\n    Process\n    {\n        foreach($service in (Get-WmiObject win32_service))\n        {\n            if($service.PathName -ne $null)\n            {\n                $path = Get-PathFromCommandLine -CommandLine $service.PathName\n            }\n            else\n            {\n                $path = $null\n            }\n\n            try\n            {\n                if($hashcache.ContainsKey($path))\n                {\n                    $md5 = $hashcache[$path].MD5\n                    $sha256 = $hashcache[$path].SHA256\n                }\n                else\n                {\n                    $md5 = Get-DIGSFileHash -Path $path -Algorithm MD5 -ErrorAction Stop\n                    $sha256 = Get-DIGSFileHash -Path $path -Algorithm SHA256 -ErrorAction Stop\n                    $obj = @{\n                        MD5 = $md5\n                        SHA256 = $sha256\n                    }\n                    $hashcache.Add($path, $obj)\n                }\n            }\n            catch\n            {\n                $md5 = $null\n                $sha256 = $null\n            }\n        \n            $Props = @{\n                Name = $service.Name\n                CommandLine = $service.PathName\n                ExecutablePath = $path\n                ServiceType = $service.ServiceType\n                StartMode = $service.StartMode\n                Caption = $service.Caption\n                Description = $service.Description\n                DisplayName = $service.DisplayName\n                ProcessId = $service.ProcessId\n                Started = $service.Started\n                User = $service.StartName\n                MD5Hash = $md5.Hash\n                SHA256Hash = $sha256.Hash\n            }\n\n            if($ReturnHashtables) {\n                $Props\n            } else {\n                New-Object -TypeName psobject -Property $Props\n            }\n        }\n    }\n\n    End\n    {\n\n    }\n}\n\nfunction Get-RegistryAutoRun\n{\n    param\n    (\n        [Parameter(ParameterSetName = 'SpecificCheck')]\n        [Switch]\n        $Logon,\n\n        [Parameter(ParameterSetName = 'SpecificCheck')]\n        [Switch]\n        $BootExecute,\n\n        [Parameter(ParameterSetName = 'SpecificCheck')]\n        [Switch]\n        $PrintMonitors,\n\n        [Parameter(ParameterSetName = 'SpecificCheck')]\n        [Switch]\n        $NetworkProviders,\n\n        [Parameter(ParameterSetName = 'SpecificCheck')]\n        [Switch]\n        $LSAProviders,\n\n        [Parameter(ParameterSetName = 'SpecificCheck')]\n        [Switch]\n        $ImageHijacks,\n\n        [Parameter(ParameterSetName = 'SpecificCheck')]\n        [Switch]\n        $AppInit,\n\n        [Parameter(ParameterSetName = 'SpecificCheck')]\n        [Switch]\n        $KnownDLLs,\n\n        [Parameter(ParameterSetName = 'SpecificCheck')]\n        [Switch]\n        $Winlogon\n    )\n\n    $UserSIDS = (Get-ChildItem -Path Registry::HKU | Where-Object { $_.PSChildName -notmatch 'S-1-5-18|S-1-5-19|S-1-5-20|\\.DEFAULT|^.*_Classes$' }).PSChildName\n\n    if (($PSCmdlet.ParameterSetName -ne 'SpecificCheck') -or $PSBoundParameters['Logon'])\n    {\n        $Category = 'Logon'\n\n        $RunKeyPaths = @(\n            'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run'\n            'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnce'\n            'SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\Run'\n            'SOFTWARE\\WOW6432Node\\Microsoft\\Windows\\CurrentVersion\\RunOnce'\n        )\n\n        $KeyList = New-Object -TypeName System.Collections.Generic.List['string']\n\n        foreach ($RunKey in $RunKeyPaths) { $KeyList.Add(\"HKLM:\\$($RunKey)\") }\n        foreach ($SID in $UserSIDS) { foreach ($RunKey in $RunKeyPaths) { $KeyList.Add(\"Registry::HKU\\$($SID)\\$($RunKey)\") } }  \n\n        foreach($result in (Get-RegistryValue -Key $KeyList.ToArray()))\n        {\n            New-AutoRunEntry -Path $result.Path -Name $result.Name -ImagePath $result.Value -Category $Category\n        }\n\n        Get-RegistryValue -Key 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\Wds\\rdpwd' -Value StartupPrograms | New-AutoRunEntry -Category $Category\n        Get-RegistryValue -Key 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon' -Value VmApplet,Userinit,Shell,TaskMan,AppSetup | New-AutoRunEntry -Category $Category\n        Get-RegistryValue -Key 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\SafeBoot' -Value AlternateShell | New-AutoRunEntry -Category $Category\n        Get-RegistryValue -Key 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows' -Value IconServiceLib | New-AutoRunEntry -Category $Category\n\n        $GPExtensionKey = 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\GPExtensions'\n        Get-ChildItem -Path $GPExtensionKey |\n            foreach { Get-RegistryValue -Key \"$($GPExtensionKey)\\$($_.PSChildName)\" -Value DllName | New-AutoRunEntry -Name $_.PSChildName -Category $Category }\n\n        <#\n        $null, 'Wow6432Node\\' | ForEach-Object {\n            $InstalledComponents = \"SOFTWARE\\$($_)Microsoft\\Active Setup\\Installed Components\"\n            Get-RegistryValue -Key \"HKLM:\\$($InstalledComponents)\" -Value StubPath | \n            ForEach-Object {\n                $AutoRunEntry = $_ | Get-CSRegistryValue -ValueName '' -ValueType REG_SZ @Timeout\n                if ($AutoRunEntry.ValueContent) { $AutoRunEntryName = $AutoRunEntry.ValueContent } else { $AutoRunEntryName = 'n/a' }\n\n                $_ | New-AutoRunsEntry -SubKey $InstalledComponents -AutoRunEntry $AutoRunEntryName -Category $Category\n            }\n        }\n        #>\n    }\n    \n    if (($PSCmdlet.ParameterSetName -ne 'SpecificCheck') -or $PSBoundParameters['BootExecute'])\n    {\n        $Category = 'BootExecute'\n\n        $SessionManager = 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Session Manager'\n        foreach ($result in (Get-RegistryValue -Key $SessionManager -Value BootExecute,SetupExecute,Execute,S0InitialCommand))\n        {\n            foreach ($val in $result.Value)\n            {\n                New-AutoRunEntry -Path $SessionManager -Name $result.Name -ImagePath $val -Category $Category\n            }\n        }\n\n        Get-RegistryValue -Key 'HKLM:\\SYSTEM\\CurrentControlSet\\Control' -Value ServiceControlManagerExtension | New-AutoRunEntry -Category $Category\n    }\n\n    if (($PSCmdlet.ParameterSetName -ne 'SpecificCheck') -or $PSBoundParameters['PrintMonitors'])\n    {\n        $Category = 'PrintMonitors'\n\n        Get-RegistryValue -Key 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Print\\Monitors' -Value Driver | New-AutoRunEntry -Category $Category\n    }\n\n    if (($PSCmdlet.ParameterSetName -ne 'SpecificCheck') -or $PSBoundParameters['NetworkProviders'])\n    {\n        $Category = 'NetworkProviders'\n\n        $Path = 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\NetworkProvider\\Order'\n        $NetworkOrder = Get-RegistryValue -Key $Path -Value ProviderOrder\n        \n        if ($NetworkOrder.Value)\n        {\n            foreach($val in ($NetworkOrder.Value.Split(',')))\n            {\n                New-AutoRunEntry -Path $Path -Name ProviderOrder -ImagePath $val -Category $Category\n            }\n        }\n    }\n\n    if (($PSCmdlet.ParameterSetName -ne 'SpecificCheck') -or $PSBoundParameters['LSAProviders'])\n    {\n        $Category = 'LSAProviders'\n\n        Get-RegistryValue -Key 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\SecurityProviders' | New-AutoRunEntry -Category $Category\n        \n        $Path = 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Lsa'\n        foreach($result in (Get-RegistryValue -Key $Path -Value 'Authentication Packages','Notification Packages')) \n        {\n            foreach($val in $result.Value)\n            {\n                New-AutoRunEntry -Path $Path -Name $result.Name -ImagePath $val -Category $Category\n            }\n        }\n\n        Get-RegistryValue -Key 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Lsa\\OSConfig' -Value 'Security Packages' | New-AutoRunEntry -Category $Category\n    }\n    \n    if (($PSCmdlet.ParameterSetName -ne 'SpecificCheck') -or $PSBoundParameters['ImageHijacks']) {\n        $Category = 'ImageHijacks'\n\n        $CommonKeys = @(\n            'SOFTWARE\\Classes\\htmlfile\\shell\\open\\command',\n            'SOFTWARE\\Classes\\htafile\\shell\\open\\command',\n            'SOFTWARE\\Classes\\batfile\\shell\\open\\command',\n            'SOFTWARE\\Classes\\comfile\\shell\\open\\command',\n            'SOFTWARE\\Classes\\piffile\\shell\\open\\command',\n            'SOFTWARE\\Classes\\exefile\\shell\\open\\command'\n        )\n\n        foreach ($CommonKey in $CommonKeys) {\n            Get-RegistryValue -Key \"HKLM:\\$($CommonKey)\" -Value '' | New-AutoRunsEntry -AutoRunEntry $CommonKey.Split('\\')[2] -Category $Category\n\n            # Iterate over each local user hive\n            foreach ($SID in $HKUSIDs) {\n                Get-CSRegistryValue -Hive HKU -SubKey \"$SID\\$CommonKey\" -ValueName '' @CommonArgs @Timeout |\n                    New-AutoRunsEntry -AutoRunEntry $CommonKey.Split('\\')[2] -Category $Category\n            }\n        }\n\n        Get-RegistryValue -Key HKLM:\\SOFTWARE\\Classes\\exefile\\shell\\open\\command -Value IsolatedCommand | New-AutoRunEntry -Category $Category\n\n        <#\n        $null, 'Wow6432Node\\' | ForEach-Object {\n            Get-RegistryValue -Key \"HKLM:\\SOFTWARE\\$($_)Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\" -Value Debugger | \n                ForEach-Object {\n                    $_ | New-AutoRunsEntry -AutoRunEntry $_.SubKey.Substring($_.SubKey.LastIndexOf('\\') + 1) -Category $Category\n                }\n\n            Get-RegistryValue -Key \"HKLM:\\SOFTWARE\\$($_)Microsoft\\Command Processor\" -ValueName Autorun | New-AutoRunsEntry -Category $Category\n        }\n\n        $Class_exe = Get-CSRegistryValue -Hive HKLM -SubKey 'HKLM:\\SOFTWARE\\Classes\\.exe' -ValueName '' -ValueType REG_SZ @CommonArgs @Timeout\n\n        if ($Class_exe.ValueContent) {\n            $OpenCommand = Get-CSRegistryValue -Hive HKLM -SubKey \"SOFTWARE\\Classes\\$($Class_exe.ValueContent)\\Shell\\Open\\Command\" -ValueName '' -ValueType REG_SZ @CommonArgs @Timeout\n\n            if ($OpenCommand.ValueContent) {\n                $OpenCommand | New-AutoRunsEntry -Hive $Class_exe.Hive -SubKey $Class_exe.SubKey -AutoRunEntry $Class_exe.ValueContent -Category $Category\n            }\n        }\n\n        $Class_cmd = Get-CSRegistryValue -Hive HKLM -SubKey 'SOFTWARE\\Classes\\.cmd' -ValueName '' -ValueType REG_SZ @CommonArgs @Timeout\n\n        if ($Class_cmd.ValueContent) {\n            $OpenCommand = Get-CSRegistryValue -Hive HKLM -SubKey \"SOFTWARE\\Classes\\$($Class_cmd.ValueContent)\\Shell\\Open\\Command\" -ValueName '' -ValueType REG_SZ @CommonArgs @Timeout\n\n            if ($OpenCommand.ValueContent) {\n                $OpenCommand | New-AutoRunsEntry -Hive $Class_cmd.Hive -SubKey $Class_cmd.SubKey -AutoRunEntry $Class_cmd.ValueContent -Category $Category\n            }\n        }\n\n        foreach ($SID in $HKUSIDs) {\n            Get-CSRegistryValue -Hive HKU -SubKey \"$SID\\SOFTWARE\\Microsoft\\Command Processor\" -ValueName 'Autorun' @CommonArgs @Timeout |\n                New-AutoRunsEntry -Category $Category\n\n            $Class_exe = Get-CSRegistryValue -Hive HKU -SubKey \"$SID\\SOFTWARE\\Classes\\.exe\" -ValueName '' -ValueType REG_SZ @CommonArgs @Timeout\n\n            if ($Class_exe.ValueContent) {\n                $OpenCommand = Get-CSRegistryValue -Hive HKU -SubKey \"$SID\\SOFTWARE\\Classes\\$($Class_exe.ValueContent)\\Shell\\Open\\Command\" -ValueName '' -ValueType REG_SZ @CommonArgs @Timeout\n\n                if ($OpenCommand.ValueContent) {\n                    $OpenCommand | New-AutoRunsEntry -Hive $Class_exe.Hive -SubKey $Class_exe.SubKey -AutoRunEntry $Class_exe.ValueContent -Category $Category\n                }\n            }\n\n            $Class_cmd = Get-CSRegistryValue -Hive HKU -SubKey \"$SID\\SOFTWARE\\Classes\\.cmd\" -ValueName '' -ValueType REG_SZ @CommonArgs @Timeout\n\n            if ($Class_cmd.ValueContent) {\n                $OpenCommand = Get-CSRegistryValue -Hive HKU -SubKey \"$SID\\SOFTWARE\\Classes\\$($Class_cmd.ValueContent)\\Shell\\Open\\Command\" -ValueName '' -ValueType REG_SZ @CommonArgs @Timeout\n\n                if ($OpenCommand.ValueContent) {\n                    $OpenCommand | New-AutoRunsEntry -Hive $Class_cmd.Hive -SubKey $Class_cmd.SubKey -AutoRunEntry $Class_cmd.ValueContent -Category $Category\n                }\n            }\n        }\n        #>\n    }\n\n    if (($PSCmdlet.ParameterSetName -ne 'SpecificCheck') -or $PSBoundParameters['AppInit']) \n    {\n        $Category = 'AppInit'\n\n        $null,'Wow6432Node\\' | ForEach-Object {\n            Get-RegistryValue -Key \"HKLM:\\SOFTWARE\\$($_)Microsoft\\Windows NT\\CurrentVersion\\Windows\" -Value 'AppInit_DLLs' | New-AutoRunEntry -Category $Category\n            Get-RegistryValue -Key \"HKLM:\\SOFTWARE\\$($_)Microsoft\\Command Processor\" -Value 'Autorun' | New-AutoRunEntry -Category $Category\n        }\n\n        Get-RegistryValue -Key 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\AppCertDlls' | New-AutoRunEntry -Category $Category\n    }\n\n    if (($PSCmdlet.ParameterSetName -ne 'SpecificCheck') -or $PSBoundParameters['KnownDLLs']) \n    {\n        $Category = 'KnownDLLs'\n\n        Get-RegistryValue -Key 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\KnownDLLs' | New-AutoRunEntry -Category $Category\n    }\n\n    <#\n    if (($PSCmdlet.ParameterSetName -ne 'SpecificCheck') -or $PSBoundParameters['Winlogon']) {\n        $Category = 'Winlogon'\n\n        $CmdLine = Get-CSRegistryValue -Hive HKLM -SubKey 'SYSTEM\\Setup' -ValueName 'CmdLine' @CommonArgs @Timeout\n\n        if ($CmdLine -and $CmdLine.ValueContent) {\n            $CmdLine | New-AutoRunsEntry -Category $Category\n        }\n\n        'Credential Providers', 'Credential Provider Filters', 'PLAP Providers' |\n            ForEach-Object { Get-CSRegistryKey -Hive HKLM -SubKey \"SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Authentication\\$_\" @CommonArgs @Timeout } | ForEach-Object {\n                $LastBSIndex = $_.SubKey.LastIndexOf('\\')\n                $ParentKey = $_.SubKey.Substring(0, $LastBSIndex)\n                $Guid = $_.SubKey.Substring($LastBSIndex + 1)\n\n                if ($Guid -as [Guid]) {\n                    $AutoRunEntry = Get-CSRegistryValue -Hive HKLM -SubKey \"SOFTWARE\\Classes\\CLSID\\$Guid\" -ValueName '' -ValueType REG_SZ @CommonArgs @Timeout\n                    $InprocServer32 = Get-CSRegistryValue -Hive HKLM -SubKey \"SOFTWARE\\Classes\\CLSID\\$Guid\\InprocServer32\" -ValueName '' -ValueType REG_EXPAND_SZ @CommonArgs @Timeout\n\n                    New-AutoRunsEntry $_.Hive $ParentKey $AutoRunEntry.ValueContent $InprocServer32.ValueContent $Category $_.PSComputerName\n                }\n            }\n\n        $BootVer = Get-CSRegistryValue -Hive HKLM -SubKey 'SYSTEM\\CurrentControlSet\\Control\\BootVerificationProgram' -ValueName 'ImagePath' @CommonArgs @Timeout\n\n        if ($BootVer) {\n            $BootVer | New-AutoRunsEntry -Hive $BootVer.Hive -SubKey \"$($BootVer.SubKey)\\ImagePath\"\n        }\n\n        foreach ($SID in $HKUSIDs) {\n            $Scrnsave = Get-CSRegistryValue -Hive HKU -SubKey \"$SID\\SOFTWARE\\Policies\\Microsoft\\Windows\\Control Panel\\Desktop\" -ValueName 'Scrnsave.exe' @CommonArgs @Timeout\n            if ($Scrnsave) { $Scrnsave | New-AutoRunsEntry }\n\n            $Scrnsave = Get-CSRegistryValue -Hive HKU -SubKey \"$SID\\Control Panel\\Desktop\" -ValueName 'Scrnsave.exe' @CommonArgs @Timeout\n            if ($Scrnsave) { $Scrnsave | New-AutoRunsEntry }\n        }\n    }\n    #>\n}\n\nfunction Get-SecurityPackage\n{\n    param\n    (\n        [Parameter()]\n        [switch]\n        $ReturnHashtables\n    )\n    <#\n    .SYNOPSIS\n\n    Enumerates Security Service Providers (SSP) t\n\n    .DESCRIPTION   \n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: None\n    Optional Dependencies: None\n\n    .EXAMPLE\n\n    PS > Get-SecurityPackage\n\n    Name         : Negotiate\n    Comment      : Microsoft Package Negotiator\n    Capabilities : INTEGRITY, PRIVACY, CONNECTION, MULTI_REQUIRED, EXTENDED_ERROR, \n                   IMPERSONATION, ACCEPT_WIN32_NAME, NEGOTIABLE, GSS_COMPATIBLE, LOGON, \n                   RESTRICTED_TOKENS, APPCONTAINER_CHECKS\n    Version      : 1\n    RpcId        : 9\n    MaxToken     : 65791\n\n    Name         : NegoExtender\n    Comment      : NegoExtender Security Package\n    Capabilities : INTEGRITY, PRIVACY, CONNECTION, IMPERSONATION, NEGOTIABLE, GSS_COMPATIBLE, \n                   LOGON, MUTUAL_AUTH, NEGO_EXTENDER, APPCONTAINER_CHECKS\n    Version      : 1\n    RpcId        : 30\n    MaxToken     : 12000\n\n    Name         : Kerberos\n    Comment      : Microsoft Kerberos V1.0\n    Capabilities : INTEGRITY, PRIVACY, TOKEN_ONLY, DATAGRAM, CONNECTION, MULTI_REQUIRED, \n                   EXTENDED_ERROR, IMPERSONATION, ACCEPT_WIN32_NAME, NEGOTIABLE, \n                   GSS_COMPATIBLE, LOGON, MUTUAL_AUTH, DELEGATION, READONLY_WITH_CHECKSUM, \n                   RESTRICTED_TOKENS, APPCONTAINER_CHECKS\n    Version      : 1\n    RpcId        : 16\n    MaxToken     : 65535\n\n    Name         : NTLM\n    Comment      : NTLM Security Package\n    Capabilities : INTEGRITY, PRIVACY, TOKEN_ONLY, CONNECTION, MULTI_REQUIRED, IMPERSONATION, \n                   ACCEPT_WIN32_NAME, NEGOTIABLE, LOGON, RESTRICTED_TOKENS, APPCONTAINER_CHECKS\n    Version      : 1\n    RpcId        : 10\n    MaxToken     : 2888\n\n    Name         : TSSSP\n    Comment      : TS Service Security Package\n    Capabilities : CONNECTION, MULTI_REQUIRED, ACCEPT_WIN32_NAME, MUTUAL_AUTH, \n                   APPCONTAINER_CHECKS\n    Version      : 1\n    RpcId        : 22\n    MaxToken     : 13000\n\n    Name         : pku2u\n    Comment      : PKU2U Security Package\n    Capabilities : INTEGRITY, PRIVACY, CONNECTION, IMPERSONATION, GSS_COMPATIBLE, MUTUAL_AUTH, \n                   NEGOTIABLE2, APPCONTAINER_CHECKS\n    Version      : 1\n    RpcId        : 31\n    MaxToken     : 12000\n\n    Name         : CloudAP\n    Comment      : Cloud AP Security Package\n    Capabilities : LOGON, NEGOTIABLE2\n    Version      : 1\n    RpcId        : 36\n    MaxToken     : 0\n\n    Name         : WDigest\n    Comment      : Digest Authentication for Windows\n    Capabilities : TOKEN_ONLY, IMPERSONATION, ACCEPT_WIN32_NAME, APPCONTAINER_CHECKS\n    Version      : 1\n    RpcId        : 21\n    MaxToken     : 4096\n\n    Name         : Schannel\n    Comment      : Schannel Security Package\n    Capabilities : INTEGRITY, PRIVACY, CONNECTION, MULTI_REQUIRED, EXTENDED_ERROR, \n                   IMPERSONATION, ACCEPT_WIN32_NAME, STREAM, MUTUAL_AUTH, \n                   APPCONTAINER_PASSTHROUGH\n    Version      : 1\n    RpcId        : 14\n    MaxToken     : 24576\n\n    Name         : Microsoft Unified Security Protocol Provider\n    Comment      : Schannel Security Package\n    Capabilities : INTEGRITY, PRIVACY, CONNECTION, MULTI_REQUIRED, EXTENDED_ERROR, \n                   IMPERSONATION, ACCEPT_WIN32_NAME, STREAM, MUTUAL_AUTH, \n                   APPCONTAINER_PASSTHROUGH\n    Version      : 1\n    RpcId        : 14\n    MaxToken     : 24576\n\n    Name         : CREDSSP\n    Comment      : Microsoft CredSSP Security Provider\n    Capabilities : INTEGRITY, PRIVACY, CONNECTION, MULTI_REQUIRED, IMPERSONATION, \n                   ACCEPT_WIN32_NAME, STREAM, MUTUAL_AUTH, APPCONTAINER_CHECKS\n    Version      : 1\n    RpcId        : 65535\n    MaxToken     : 90567\n    #>\n\n    $obj = EnumerateSecurityPackages\n\n    if($ReturnHashtables)\n    {\n        foreach($o in $obj)\n        {\n            $props = @{\n                Name = $o.Name\n                Comment = $o.Comment\n                Capabilities = $o.Capabilities\n                Version = $o.Version\n                RpcId = $o.RpcId\n                MaxToken = $o.MaxToken\n            }\n\n            Write-Output $props\n        }\n    }\n    else\n    {\n        Write-Output $obj\n    }\n}\n\nfunction Get-SimpleNamedPipe\n{ \n<#\n    .SYNOPSIS\n\n        Gets a list of open named pipes.\n\n        Author: Greg Zakharov\n        License: \n        Required Dependencies: None\n        Optional Dependencies: None\n\n    .DESCRIPTION\n\n        When defining custom enums, structs, and unmanaged functions, it is\n        necessary to associate to an assembly module. This helper function\n        creates an in-memory module that can be passed to the 'enum',\n        'struct', and Add-Win32Type functions.\n#>\n    [CmdletBinding()]\n    Param (\n        [switch]\n        $ReturnHashtables\n    )\n\n    Begin \n    {\n        $Mscorlib = [AppDomain]::CurrentDomain.GetAssemblies() | ? { \n            $_.ManifestModule.ScopeName.Equals('CommonLanguageRuntimeLibrary') \n        } \n     \n        $SafeFindHandle = $Mscorlib.GetType('Microsoft.Win32.SafeHandles.SafeFindHandle') \n        $Win32Native = $Mscorlib.GetType('Microsoft.Win32.Win32Native') \n     \n        $WIN32_FIND_DATA = $Win32Native.GetNestedType( \n            'WIN32_FIND_DATA', [Reflection.BindingFlags]32 \n        ) \n        $FindFirstFile = $Win32Native.GetMethod( \n            'FindFirstFile', [Reflection.BindingFlags]40, \n            $null, @([String], $WIN32_FIND_DATA), $null \n        ) \n        $FindNextFile = $Win32Native.GetMethod('FindNextFile', [Reflection.BindingFlags]40, $null, @($SafeFindHandle, $WIN32_FIND_DATA), $null) \n     \n        $Obj = $WIN32_FIND_DATA.GetConstructors()[0].Invoke($null)\n        function Read-Field([String]$Field) { \n            return $WIN32_FIND_DATA.GetField($Field, [Reflection.BindingFlags]36).GetValue($Obj)\n        } \n    } \n\n    Process \n    { \n        $Handle = $FindFirstFile.Invoke($null, @('\\\\.\\pipe\\*', $obj))\n\n        \n        $Output = @{\n            Name = [string](Read-Field cFileName)\n            Instances = [UInt32](Read-Field nFileSizeLow)\n        }\n\n        do {\n            $Output = @{\n                Name = [string](Read-Field cFileName)\n                Instances = [UInt32](Read-Field nFileSizeLow)\n            }\n\n            if($ReturnHashtables) {\n                $Output\n            } else {\n                New-Object PSObject -Property $Output\n            }\n        } while($FindNextFile.Invoke($null, @($Handle, $obj)))\n     \n        $Handle.Close() \n    } \n\n    End \n    {\n    \n    } \n}\n\nfunction Get-WmiEventSubscription\n{\n    foreach($o in (Get-WmiObject -Namespace root\\subscription -Class __EventConsumer))\n    {\n        $Sid = New-Object System.Security.Principal.SecurityIdentifier(@($o.CreatorSID,$null))\n        $UserName = $Sid.Translate([System.Security.Principal.NTAccount])\n        \n        switch($o.__CLASS)\n        {\n            ActiveScriptEventConsumer\n            {\n                $props = @{\n                    CreatorSid = $Sid.Value\n                    CreatorUserName = $UserName\n                    KillTimeout = $o.KillTimeout\n                    MachineName = $o.MachineName\n                    MaximumQueueSize = $o.MaximumQueueSize\n                    Name = $o.Name\n                    ScriptFilename = $o.ScriptFilename\n                    ScriptingEngine = $o.ScriptingEngine\n                    ScriptText = $o.ScriptText\n                    Class = $o.ClassPath.ClassName\n                    ClassPath = $o.ClassPath.Path\n                }\n            }\n            CommandLineEventConsumer\n            {\n                $props = @{\n                    CreatorSid = $Sid.Value\n                    CreatorUserName = $UserName\n                    MachineName = $o.MachineName\n                    MaximumQueueSize = $o.MaximumQueueSize\n                    CommandLineTemplate = $o.CommandLineTemplate\n                    CreateNewConsole = $o.CreateNewConsole\n                    CreateNewProcessGroup = $o.CreateNewProcessGroup\n                    CreateSeparateWowVdm = $o.CreateSeparateWowVdm\n                    CreateSharedWowVdm = $o.CreateSharedWowVdm\n                    DesktopName = $o.DesktopName\n                    ExecutablePath = $o.ExecutablePath\n                    FillAttributes = $o.FillAttributes\n                    ForceOffFeedback = $o.ForceOffFeedback\n                    ForceOnFeedback = $o.ForceOnFeedback\n                    KillTimeout = $o.KillTimeout\n                    Name = $o.Name\n                    Priority = $o.Priority\n                    RunInteractively = $o.RunInteractively\n                    ShowWindowCommand = $o.ShowWindowCommand\n                    UseDefaultErrorMode = $o.UseDefaultErrorMode\n                    WindowTitle = $o.WindowTitle\n                    WorkingDirectory = $o.WorkingDirectory\n                    XCoordinate = $o.XCoordinate\n                    XNumCharacters = $o.XNumCharacters\n                    XSize = $o.XSize\n                    YCoordinate = $o.YCoordinate\n                    YNumCharacters = $o.YNumCharacters\n                    YSize = $o.YSize\n                    FillAttribute = $o.FillAttribute\n                    Class = $o.ClassPath.ClassName\n                    ClassPath = $o.ClassPath.Path\n                }\n            }\n            LogFileEventConsumer\n            {\n                $props = @{\n                    CreatorSid = $Sid.Value\n                    CreatorUserName = $UserName\n                    MachineName = $o.MachineName\n                    MaximumQueueSize = $o.MaximumQueueSize\n                    Filename = $o.Filename\n                    IsUnicode = $o.IsUnicode\n                    MaximumFileSize = $o.MaximumFileSize\n                    Name = $o.Name\n                    Text = $o.Text\n                    Class = $o.ClassPath.ClassName\n                    ClassPath = $o.ClassPath.Path\n                }\n            }\n            NtEventLogEventConsumer\n            {\n                $props = @{\n                    Category = $o.Category\n                    CreatorSid = $Sid.Value\n                    CreatorUserName = $UserName\n                    EventId = $o.EventID\n                    EventType = $o.EventType\n                    InsertionStringTemplates = $o.InsertionStringTemplates\n                    MachineName = $o.MachineName\n                    MaximumQueueSize = $o.MaximumQueueSize\n                    Name = $o.Name\n                    NameOfRawDataProperty = $o.NameOfRawDataProperty\n                    NameOfUserSidProperty = $o.NameOfUserSIDProperty\n                    NumberOfInsertionStrings = $o.NumberOfInsertionStrings\n                    SourceName = $o.SourceName\n                    UncServerName = $o.UNCServerName\n                    Class = $o.ClassPath.ClassName\n                    ClassPath = $o.ClassPath.Path\n                }\n            }\n            SMTPEventConsumer\n            {\n                $props = @{\n                    CreatorSid = $Sid.Value\n                    CreatorUserName = $UserName\n                    MachineName = $o.MachineName\n                    MaximumQueueSize = $o.MaximumQueueSize\n                    BccLine = $o.BccLine\n                    CcLine = $o.CcLine\n                    FromLine = $o.FromLine\n                    HeaderFields = $o.HeaderFields\n                    Message = $o.Message\n                    Name = $o.Name\n                    ReplyToLine = $o.ReplyToLine\n                    SMTPServer = $o.SMTPServer\n                    Subject = $o.Subject\n                    ToLine = $o.ToLine\n                    Class = $o.ClassPath.ClassName\n                    ClassPath = $o.ClassPath.Path\n                }\n            }\n            default\n            {\n                $props = @{\n                    CreatorSid = $Sid.Value\n                    CreatorUserName = $UserName\n                    Name = $o.Name\n                    Class = $o.ClassPath.ClassName\n                    ClassPath = $o.ClassPath.Path\n                }\n            }\n        }\n        Write-Output $props\n    }\n}\n#endregion Collection Functions\n\n#region Helper Functions\nfunction Get-System\n{\n    <#\n    .SYNOPSIS\n\n    .DESCRIPTION\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: None\n    Optional Dependencies: None\n        \n    .LINK\n\n    .EXAMPLE\n    #>\n\n    # Get a Process object for the winlogon process\n    # The System.Diagnostics.Process class has a handle property that we can use\n    # We know winlogon will be available and is running as NT AUTHORITY\\SYSTEM\n    $winlogons = Get-Process -Name winlogon\n\n    try\n    {\n        $proc = $winlogons[0]\n    }\n    catch\n    {\n        $proc = $winlogons\n    }\n\n    # Open winlogon's Token with TOKEN_DUPLICATE Acess\n    # This allows us to make a copy of the token with DuplicateToken\n    $hToken = OpenProcessToken -ProcessHandle $proc.Handle -DesiredAccess TOKEN_DUPLICATE\n    \n    # Make a copy of the NT AUTHORITY\\SYSTEM Token\n    $hDupToken = DuplicateToken -TokenHandle $hToken\n    \n    # Apply our Duplicated Token to our Thread\n    ImpersonateLoggedOnUser -TokenHandle $hDupToken\n    \n    # Clean up the handles we created\n    CloseHandle -Handle $hToken\n    CloseHandle -Handle $hDupToken\n\n    if(-not [System.Security.Principal.WindowsIdentity]::GetCurrent().Name -eq 'NT AUTHORITY\\SYSTEM')\n    {\n        throw \"Unable to Impersonate System Token\"\n    }\n}\n\nfunction Get-RegistryValue\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string[]]\n        $Key,\n\n        [Parameter()]\n        [string[]]\n        $Value\n    )\n\n    foreach($k in $key)\n    {\n        try\n        {\n            foreach($val in ((Get-ItemProperty -Path $k -ErrorAction Stop).PSObject.Properties | Where-Object { $_.MemberType -eq 'NoteProperty' -and $_.Name -notmatch 'PS(Path|Drive|Provider|ParentPath|ChildName)|\\(default\\)' }))\n            {\n                if($PSBoundParameters.ContainsKey('Value'))\n                {\n                    if($Value -contains $val.Name)\n                    {\n                        $props = @{\n                            Path = $k\n                            Name = $val.Name\n                            Value = $val.Value\n                        }\n\n                        New-Object -TypeName psobject -Property $props\n                    }\n                }\n                else\n                {\n                    $props = @{\n                        Path = $k\n                        Name = $val.Name\n                        Value = $val.Value\n                    }\n\n                    New-Object -TypeName psobject -Property $props\n                }\n            }\n        }\n        catch\n        {\n\n        }\n    }\n}\n\nfunction New-AutoRunEntry\n{\n    param\n    (\n        [Parameter(Position = 0, ValueFromPipelineByPropertyName = $true)]\n        [string]\n        $Path,\n    \n        [Parameter(Position = 1, ValueFromPipelineByPropertyName = $true)]\n        [string]\n        $Name,\n\n        [Parameter(Position = 2, ValueFromPipelineByPropertyName = $true)]\n        [Alias('Value')]\n        [string]\n        $ImagePath,\n\n        [Parameter(Position = 3, ValueFromPipelineByPropertyName = $true)]\n        [string]\n        $Category\n    )\n\n    process\n    {\n        if($ImagePath -ne $null)\n        {\n            @{\n                Path = $Path\n                Name = $Name\n                ImagePath = $ImagePath\n                Type = $Category\n            }\n        }\n    }\n}\n#endregion Helper Functions\n\n#region PSReflect\nfunction New-InMemoryModule\n{\n<#\n.SYNOPSIS\n\nCreates an in-memory assembly and module\n\nAuthor: Matthew Graeber (@mattifestation)\nLicense: BSD 3-Clause\nRequired Dependencies: None\nOptional Dependencies: None\n \n.DESCRIPTION\n\nWhen defining custom enums, structs, and unmanaged functions, it is\nnecessary to associate to an assembly module. This helper function\ncreates an in-memory module that can be passed to the 'enum',\n'struct', and Add-Win32Type functions.\n\n.PARAMETER ModuleName\n\nSpecifies the desired name for the in-memory assembly and module. If\nModuleName is not provided, it will default to a GUID.\n\n.EXAMPLE\n\n$Module = New-InMemoryModule -ModuleName Win32\n#>\n\n    Param\n    (\n        [Parameter(Position = 0)]\n        [ValidateNotNullOrEmpty()]\n        [String]\n        $ModuleName = [Guid]::NewGuid().ToString()\n    )\n\n    $AppDomain = [Reflection.Assembly].Assembly.GetType('System.AppDomain').GetProperty('CurrentDomain').GetValue($null, @())\n    $LoadedAssemblies = $AppDomain.GetAssemblies()\n\n    foreach ($Assembly in $LoadedAssemblies) {\n        if ($Assembly.FullName -and ($Assembly.FullName.Split(',')[0] -eq $ModuleName)) {\n            return $Assembly\n        }\n    }\n\n    $DynAssembly = New-Object Reflection.AssemblyName($ModuleName)\n    $Domain = $AppDomain\n    $AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, 'Run')\n    $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule($ModuleName, $False)\n\n    return $ModuleBuilder\n}\n\n# A helper function used to reduce typing while defining function\n# prototypes for Add-Win32Type.\nfunction func\n{\n    Param\n    (\n        [Parameter(Position = 0, Mandatory = $True)]\n        [String]\n        $DllName,\n\n        [Parameter(Position = 1, Mandatory = $True)]\n        [string]\n        $FunctionName,\n\n        [Parameter(Position = 2, Mandatory = $True)]\n        [Type]\n        $ReturnType,\n\n        [Parameter(Position = 3)]\n        [Type[]]\n        $ParameterTypes,\n\n        [Parameter(Position = 4)]\n        [Runtime.InteropServices.CallingConvention]\n        $NativeCallingConvention,\n\n        [Parameter(Position = 5)]\n        [Runtime.InteropServices.CharSet]\n        $Charset,\n\n        [String]\n        $EntryPoint,\n\n        [Switch]\n        $SetLastError\n    )\n\n    $Properties = @{\n        DllName = $DllName\n        FunctionName = $FunctionName\n        ReturnType = $ReturnType\n    }\n\n    if ($ParameterTypes) { $Properties['ParameterTypes'] = $ParameterTypes }\n    if ($NativeCallingConvention) { $Properties['NativeCallingConvention'] = $NativeCallingConvention }\n    if ($Charset) { $Properties['Charset'] = $Charset }\n    if ($SetLastError) { $Properties['SetLastError'] = $SetLastError }\n    if ($EntryPoint) { $Properties['EntryPoint'] = $EntryPoint }\n\n    New-Object PSObject -Property $Properties\n}\n\nfunction Add-Win32Type\n{\n<#\n.SYNOPSIS\n\nCreates a .NET type for an unmanaged Win32 function.\n\nAuthor: Matthew Graeber (@mattifestation)\nLicense: BSD 3-Clause\nRequired Dependencies: None\nOptional Dependencies: func\n \n.DESCRIPTION\n\nAdd-Win32Type enables you to easily interact with unmanaged (i.e.\nWin32 unmanaged) functions in PowerShell. After providing\nAdd-Win32Type with a function signature, a .NET type is created\nusing reflection (i.e. csc.exe is never called like with Add-Type).\n\nThe 'func' helper function can be used to reduce typing when defining\nmultiple function definitions.\n\n.PARAMETER DllName\n\nThe name of the DLL.\n\n.PARAMETER FunctionName\n\nThe name of the target function.\n\n.PARAMETER EntryPoint\n\nThe DLL export function name. This argument should be specified if the\nspecified function name is different than the name of the exported\nfunction.\n\n.PARAMETER ReturnType\n\nThe return type of the function.\n\n.PARAMETER ParameterTypes\n\nThe function parameters.\n\n.PARAMETER NativeCallingConvention\n\nSpecifies the native calling convention of the function. Defaults to\nstdcall.\n\n.PARAMETER Charset\n\nIf you need to explicitly call an 'A' or 'W' Win32 function, you can\nspecify the character set.\n\n.PARAMETER SetLastError\n\nIndicates whether the callee calls the SetLastError Win32 API\nfunction before returning from the attributed method.\n\n.PARAMETER Module\n\nThe in-memory module that will host the functions. Use\nNew-InMemoryModule to define an in-memory module.\n\n.PARAMETER Namespace\n\nAn optional namespace to prepend to the type. Add-Win32Type defaults\nto a namespace consisting only of the name of the DLL.\n\n.EXAMPLE\n\n$Mod = New-InMemoryModule -ModuleName Win32\n\n$FunctionDefinitions = @(\n    (func kernel32 GetProcAddress ([IntPtr]) @([IntPtr], [String]) -Charset Ansi -SetLastError),\n    (func kernel32 GetModuleHandle ([Intptr]) @([String]) -SetLastError),\n    (func ntdll RtlGetCurrentPeb ([IntPtr]) @())\n)\n\n$Types = $FunctionDefinitions | Add-Win32Type -Module $Mod -Namespace 'Win32'\n$Kernel32 = $Types['kernel32']\n$Ntdll = $Types['ntdll']\n$Ntdll::RtlGetCurrentPeb()\n$ntdllbase = $Kernel32::GetModuleHandle('ntdll')\n$Kernel32::GetProcAddress($ntdllbase, 'RtlGetCurrentPeb')\n\n.NOTES\n\nInspired by Lee Holmes' Invoke-WindowsApi http://poshcode.org/2189\n\nWhen defining multiple function prototypes, it is ideal to provide\nAdd-Win32Type with an array of function signatures. That way, they\nare all incorporated into the same in-memory module.\n#>\n\n    [OutputType([Hashtable])]\n    Param(\n        [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)]\n        [String]\n        $DllName,\n\n        [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)]\n        [String]\n        $FunctionName,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [String]\n        $EntryPoint,\n\n        [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)]\n        [Type]\n        $ReturnType,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [Type[]]\n        $ParameterTypes,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [Runtime.InteropServices.CallingConvention]\n        $NativeCallingConvention = [Runtime.InteropServices.CallingConvention]::StdCall,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [Runtime.InteropServices.CharSet]\n        $Charset = [Runtime.InteropServices.CharSet]::Auto,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [Switch]\n        $SetLastError,\n\n        [Parameter(Mandatory = $True)]\n        [ValidateScript({($_ -is [Reflection.Emit.ModuleBuilder]) -or ($_ -is [Reflection.Assembly])})]\n        $Module,\n\n        [ValidateNotNull()]\n        [String]\n        $Namespace = ''\n    )\n\n    BEGIN\n    {\n        $TypeHash = @{}\n    }\n\n    PROCESS\n    {\n        if ($Module -is [Reflection.Assembly])\n        {\n            if ($Namespace)\n            {\n                $TypeHash[$DllName] = $Module.GetType(\"$Namespace.$DllName\")\n            }\n            else\n            {\n                $TypeHash[$DllName] = $Module.GetType($DllName)\n            }\n        }\n        else\n        {\n            # Define one type for each DLL\n            if (!$TypeHash.ContainsKey($DllName))\n            {\n                if ($Namespace)\n                {\n                    $TypeHash[$DllName] = $Module.DefineType(\"$Namespace.$DllName\", 'Public,BeforeFieldInit')\n                }\n                else\n                {\n                    $TypeHash[$DllName] = $Module.DefineType($DllName, 'Public,BeforeFieldInit')\n                }\n            }\n\n            $Method = $TypeHash[$DllName].DefineMethod(\n                $FunctionName,\n                'Public,Static,PinvokeImpl',\n                $ReturnType,\n                $ParameterTypes)\n\n            # Make each ByRef parameter an Out parameter\n            $i = 1\n            foreach($Parameter in $ParameterTypes)\n            {\n                if ($Parameter.IsByRef)\n                {\n                    [void] $Method.DefineParameter($i, 'Out', $null)\n                }\n\n                $i++\n            }\n\n            $DllImport = [Runtime.InteropServices.DllImportAttribute]\n            $SetLastErrorField = $DllImport.GetField('SetLastError')\n            $CallingConventionField = $DllImport.GetField('CallingConvention')\n            $CharsetField = $DllImport.GetField('CharSet')\n            $EntryPointField = $DllImport.GetField('EntryPoint')\n            if ($SetLastError) { $SLEValue = $True } else { $SLEValue = $False }\n\n            if ($PSBoundParameters['EntryPoint']) { $ExportedFuncName = $EntryPoint } else { $ExportedFuncName = $FunctionName }\n\n            # Equivalent to C# version of [DllImport(DllName)]\n            $Constructor = [Runtime.InteropServices.DllImportAttribute].GetConstructor([String])\n            $DllImportAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($Constructor,\n                $DllName, [Reflection.PropertyInfo[]] @(), [Object[]] @(),\n                [Reflection.FieldInfo[]] @($SetLastErrorField,\n                                            $CallingConventionField,\n                                            $CharsetField,\n                                            $EntryPointField),\n                [Object[]] @($SLEValue,\n                                ([Runtime.InteropServices.CallingConvention] $NativeCallingConvention),\n                                ([Runtime.InteropServices.CharSet] $Charset),\n                                $ExportedFuncName))\n\n            $Method.SetCustomAttribute($DllImportAttribute)\n        }\n    }\n\n    END\n    {\n        if ($Module -is [Reflection.Assembly])\n        {\n            return $TypeHash\n        }\n\n        $ReturnTypes = @{}\n\n        foreach ($Key in $TypeHash.Keys)\n        {\n            $Type = $TypeHash[$Key].CreateType()\n            \n            $ReturnTypes[$Key] = $Type\n        }\n\n        return $ReturnTypes\n    }\n}\n\nfunction psenum\n{\n<#\n.SYNOPSIS\n\nCreates an in-memory enumeration for use in your PowerShell session.\n\nAuthor: Matthew Graeber (@mattifestation)\nLicense: BSD 3-Clause\nRequired Dependencies: None\nOptional Dependencies: None\n \n.DESCRIPTION\n\nThe 'psenum' function facilitates the creation of enums entirely in\nmemory using as close to a \"C style\" as PowerShell will allow.\n\n.PARAMETER Module\n\nThe in-memory module that will host the enum. Use\nNew-InMemoryModule to define an in-memory module.\n\n.PARAMETER FullName\n\nThe fully-qualified name of the enum.\n\n.PARAMETER Type\n\nThe type of each enum element.\n\n.PARAMETER EnumElements\n\nA hashtable of enum elements.\n\n.PARAMETER Bitfield\n\nSpecifies that the enum should be treated as a bitfield.\n\n.EXAMPLE\n\n$Mod = New-InMemoryModule -ModuleName Win32\n\n$ImageSubsystem = psenum $Mod PE.IMAGE_SUBSYSTEM UInt16 @{\n    UNKNOWN =                  0\n    NATIVE =                   1 # Image doesn't require a subsystem.\n    WINDOWS_GUI =              2 # Image runs in the Windows GUI subsystem.\n    WINDOWS_CUI =              3 # Image runs in the Windows character subsystem.\n    OS2_CUI =                  5 # Image runs in the OS/2 character subsystem.\n    POSIX_CUI =                7 # Image runs in the Posix character subsystem.\n    NATIVE_WINDOWS =           8 # Image is a native Win9x driver.\n    WINDOWS_CE_GUI =           9 # Image runs in the Windows CE subsystem.\n    EFI_APPLICATION =          10\n    EFI_BOOT_SERVICE_DRIVER =  11\n    EFI_RUNTIME_DRIVER =       12\n    EFI_ROM =                  13\n    XBOX =                     14\n    WINDOWS_BOOT_APPLICATION = 16\n}\n\n.NOTES\n\nPowerShell purists may disagree with the naming of this function but\nagain, this was developed in such a way so as to emulate a \"C style\"\ndefinition as closely as possible. Sorry, I'm not going to name it\nNew-Enum. :P\n#>\n\n    [OutputType([Type])]\n    Param\n    (\n        [Parameter(Position = 0, Mandatory = $True)]\n        [ValidateScript({($_ -is [Reflection.Emit.ModuleBuilder]) -or ($_ -is [Reflection.Assembly])})]\n        $Module,\n\n        [Parameter(Position = 1, Mandatory = $True)]\n        [ValidateNotNullOrEmpty()]\n        [String]\n        $FullName,\n\n        [Parameter(Position = 2, Mandatory = $True)]\n        [Type]\n        $Type,\n\n        [Parameter(Position = 3, Mandatory = $True)]\n        [ValidateNotNullOrEmpty()]\n        [Hashtable]\n        $EnumElements,\n\n        [Switch]\n        $Bitfield\n    )\n\n    if ($Module -is [Reflection.Assembly])\n    {\n        return ($Module.GetType($FullName))\n    }\n\n    $EnumType = $Type -as [Type]\n\n    $EnumBuilder = $Module.DefineEnum($FullName, 'Public', $EnumType)\n\n    if ($Bitfield)\n    {\n        $FlagsConstructor = [FlagsAttribute].GetConstructor(@())\n        $FlagsCustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($FlagsConstructor, @())\n        $EnumBuilder.SetCustomAttribute($FlagsCustomAttribute)\n    }\n\n    foreach ($Key in $EnumElements.Keys)\n    {\n        # Apply the specified enum type to each element\n        $null = $EnumBuilder.DefineLiteral($Key, $EnumElements[$Key] -as $EnumType)\n    }\n\n    $EnumBuilder.CreateType()\n}\n\n# A helper function used to reduce typing while defining struct\n# fields.\nfunction field\n{\n    Param\n    (\n        [Parameter(Position = 0, Mandatory = $True)]\n        [UInt16]\n        $Position,\n        \n        [Parameter(Position = 1, Mandatory = $True)]\n        [Type]\n        $Type,\n        \n        [Parameter(Position = 2)]\n        [UInt16]\n        $Offset,\n        \n        [Object[]]\n        $MarshalAs\n    )\n\n    @{\n        Position = $Position\n        Type = $Type -as [Type]\n        Offset = $Offset\n        MarshalAs = $MarshalAs\n    }\n}\n\nfunction struct\n{\n<#\n.SYNOPSIS\n\nCreates an in-memory struct for use in your PowerShell session.\n\nAuthor: Matthew Graeber (@mattifestation)\nLicense: BSD 3-Clause\nRequired Dependencies: None\nOptional Dependencies: field\n \n.DESCRIPTION\n\nThe 'struct' function facilitates the creation of structs entirely in\nmemory using as close to a \"C style\" as PowerShell will allow. Struct\nfields are specified using a hashtable where each field of the struct\nis comprosed of the order in which it should be defined, its .NET\ntype, and optionally, its offset and special marshaling attributes.\n\nOne of the features of 'struct' is that after your struct is defined,\nit will come with a built-in GetSize method as well as an explicit\nconverter so that you can easily cast an IntPtr to the struct without\nrelying upon calling SizeOf and/or PtrToStructure in the Marshal\nclass.\n\n.PARAMETER Module\n\nThe in-memory module that will host the struct. Use\nNew-InMemoryModule to define an in-memory module.\n\n.PARAMETER FullName\n\nThe fully-qualified name of the struct.\n\n.PARAMETER StructFields\n\nA hashtable of fields. Use the 'field' helper function to ease\ndefining each field.\n\n.PARAMETER PackingSize\n\nSpecifies the memory alignment of fields.\n\n.PARAMETER ExplicitLayout\n\nIndicates that an explicit offset for each field will be specified.\n\n.EXAMPLE\n\n$Mod = New-InMemoryModule -ModuleName Win32\n\n$ImageDosSignature = psenum $Mod PE.IMAGE_DOS_SIGNATURE UInt16 @{\n    DOS_SIGNATURE =    0x5A4D\n    OS2_SIGNATURE =    0x454E\n    OS2_SIGNATURE_LE = 0x454C\n    VXD_SIGNATURE =    0x454C\n}\n\n$ImageDosHeader = struct $Mod PE.IMAGE_DOS_HEADER @{\n    e_magic =    field 0 $ImageDosSignature\n    e_cblp =     field 1 UInt16\n    e_cp =       field 2 UInt16\n    e_crlc =     field 3 UInt16\n    e_cparhdr =  field 4 UInt16\n    e_minalloc = field 5 UInt16\n    e_maxalloc = field 6 UInt16\n    e_ss =       field 7 UInt16\n    e_sp =       field 8 UInt16\n    e_csum =     field 9 UInt16\n    e_ip =       field 10 UInt16\n    e_cs =       field 11 UInt16\n    e_lfarlc =   field 12 UInt16\n    e_ovno =     field 13 UInt16\n    e_res =      field 14 UInt16[] -MarshalAs @('ByValArray', 4)\n    e_oemid =    field 15 UInt16\n    e_oeminfo =  field 16 UInt16\n    e_res2 =     field 17 UInt16[] -MarshalAs @('ByValArray', 10)\n    e_lfanew =   field 18 Int32\n}\n\n# Example of using an explicit layout in order to create a union.\n$TestUnion = struct $Mod TestUnion @{\n    field1 = field 0 UInt32 0\n    field2 = field 1 IntPtr 0\n} -ExplicitLayout\n\n.NOTES\n\nPowerShell purists may disagree with the naming of this function but\nagain, this was developed in such a way so as to emulate a \"C style\"\ndefinition as closely as possible. Sorry, I'm not going to name it\nNew-Struct. :P\n#>\n\n    [OutputType([Type])]\n    Param\n    (\n        [Parameter(Position = 1, Mandatory = $True)]\n        [ValidateScript({($_ -is [Reflection.Emit.ModuleBuilder]) -or ($_ -is [Reflection.Assembly])})]\n        $Module,\n\n        [Parameter(Position = 2, Mandatory = $True)]\n        [ValidateNotNullOrEmpty()]\n        [String]\n        $FullName,\n\n        [Parameter(Position = 3, Mandatory = $True)]\n        [ValidateNotNullOrEmpty()]\n        [Hashtable]\n        $StructFields,\n\n        [Reflection.Emit.PackingSize]\n        $PackingSize = [Reflection.Emit.PackingSize]::Unspecified,\n\n        [Switch]\n        $ExplicitLayout\n    )\n\n    if ($Module -is [Reflection.Assembly])\n    {\n        return ($Module.GetType($FullName))\n    }\n\n    [Reflection.TypeAttributes] $StructAttributes = 'AnsiClass,\n        Class,\n        Public,\n        Sealed,\n        BeforeFieldInit'\n\n    if ($ExplicitLayout)\n    {\n        $StructAttributes = $StructAttributes -bor [Reflection.TypeAttributes]::ExplicitLayout\n    }\n    else\n    {\n        $StructAttributes = $StructAttributes -bor [Reflection.TypeAttributes]::SequentialLayout\n    }\n\n    $StructBuilder = $Module.DefineType($FullName, $StructAttributes, [ValueType], $PackingSize)\n    $ConstructorInfo = [Runtime.InteropServices.MarshalAsAttribute].GetConstructors()[0]\n    $SizeConst = @([Runtime.InteropServices.MarshalAsAttribute].GetField('SizeConst'))\n\n    $Fields = New-Object Hashtable[]($StructFields.Count)\n\n    # Sort each field according to the orders specified\n    # Unfortunately, PSv2 doesn't have the luxury of the\n    # hashtable [Ordered] accelerator.\n    foreach ($Field in $StructFields.Keys)\n    {\n        $Index = $StructFields[$Field]['Position']\n        $Fields[$Index] = @{FieldName = $Field; Properties = $StructFields[$Field]}\n    }\n\n    foreach ($Field in $Fields)\n    {\n        $FieldName = $Field['FieldName']\n        $FieldProp = $Field['Properties']\n\n        $Offset = $FieldProp['Offset']\n        $Type = $FieldProp['Type']\n        $MarshalAs = $FieldProp['MarshalAs']\n\n        $NewField = $StructBuilder.DefineField($FieldName, $Type, 'Public')\n\n        if ($MarshalAs)\n        {\n            $UnmanagedType = $MarshalAs[0] -as ([Runtime.InteropServices.UnmanagedType])\n            if ($MarshalAs[1])\n            {\n                $Size = $MarshalAs[1]\n                $AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($ConstructorInfo,\n                    $UnmanagedType, $SizeConst, @($Size))\n            }\n            else\n            {\n                $AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($ConstructorInfo, [Object[]] @($UnmanagedType))\n            }\n            \n            $NewField.SetCustomAttribute($AttribBuilder)\n        }\n\n        if ($ExplicitLayout) { $NewField.SetOffset($Offset) }\n    }\n\n    # Make the struct aware of its own size.\n    # No more having to call [Runtime.InteropServices.Marshal]::SizeOf!\n    $SizeMethod = $StructBuilder.DefineMethod('GetSize',\n        'Public, Static',\n        [Int],\n        [Type[]] @())\n    $ILGenerator = $SizeMethod.GetILGenerator()\n    # Thanks for the help, Jason Shirk!\n    $ILGenerator.Emit([Reflection.Emit.OpCodes]::Ldtoken, $StructBuilder)\n    $ILGenerator.Emit([Reflection.Emit.OpCodes]::Call,\n        [Type].GetMethod('GetTypeFromHandle'))\n    $ILGenerator.Emit([Reflection.Emit.OpCodes]::Call,\n        [Runtime.InteropServices.Marshal].GetMethod('SizeOf', [Type[]] @([Type])))\n    $ILGenerator.Emit([Reflection.Emit.OpCodes]::Ret)\n\n    # Allow for explicit casting from an IntPtr\n    # No more having to call [Runtime.InteropServices.Marshal]::PtrToStructure!\n    $ImplicitConverter = $StructBuilder.DefineMethod('op_Implicit',\n        'PrivateScope, Public, Static, HideBySig, SpecialName',\n        $StructBuilder,\n        [Type[]] @([IntPtr]))\n    $ILGenerator2 = $ImplicitConverter.GetILGenerator()\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Nop)\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ldarg_0)\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ldtoken, $StructBuilder)\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Call,\n        [Type].GetMethod('GetTypeFromHandle'))\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Call,\n        [Runtime.InteropServices.Marshal].GetMethod('PtrToStructure', [Type[]] @([IntPtr], [Type])))\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Unbox_Any, $StructBuilder)\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ret)\n\n    $StructBuilder.CreateType()\n}\n#endregion PSReflect\n\n$Module = New-InMemoryModule -ModuleName ACE\n\n#region Enums\n$KERB_PROTOCOL_MESSAGE_TYPE = psenum $Module KERB_PROTOCOL_MESSAGE_TYPE UInt32 @{ \n    KerbDebugRequestMessage                  = 0\n    KerbQueryTicketCacheMessage              = 1\n    KerbChangeMachinePasswordMessage         = 2\n    KerbVerifyPacMessage                     = 3\n    KerbRetrieveTicketMessage                = 4\n    KerbUpdateAddressesMessage               = 5\n    KerbPurgeTicketCacheMessage              = 6\n    KerbChangePasswordMessage                = 7\n    KerbRetrieveEncodedTicketMessage         = 8\n    KerbDecryptDataMessage                   = 9\n    KerbAddBindingCacheEntryMessage          = 10\n    KerbSetPasswordMessage                   = 11\n    KerbSetPasswordExMessage                 = 12\n    KerbVerifyCredentialsMessage             = 13\n    KerbQueryTicketCacheExMessage            = 14\n    KerbPurgeTicketCacheExMessage            = 15\n    KerbRefreshSmartcardCredentialsMessage   = 16\n    KerbAddExtraCredentialsMessage           = 17\n    KerbQuerySupplementalCredentialsMessage  = 18\n    KerbTransferCredentialsMessage           = 19\n    KerbQueryTicketCacheEx2Message           = 20\n    KerbSubmitTicketMessage                  = 21\n    KerbAddExtraCredentialsExMessage         = 22\n    KerbQueryKdcProxyCacheMessage            = 23\n    KerbPurgeKdcProxyCacheMessage            = 24\n    KerbQueryTicketCacheEx3Message           = 25\n    KerbCleanupMachinePkinitCredsMessage     = 26\n    KerbAddBindingCacheEntryExMessage        = 27\n    KerbQueryBindingCacheMessage             = 28\n    KerbPurgeBindingCacheMessage             = 29\n    KerbQueryDomainExtendedPoliciesMessage   = 30\n    KerbQueryS4U2ProxyCacheMessage           = 31\n}\n\n$KERB_CACHE_OPTIONS = psenum $Module KERB_CACHE_OPTIONS UInt64 @{\n    KERB_RETRIEVE_TICKET_DONT_USE_CACHE = 0x1\n    KERB_RETRIEVE_TICKET_USE_CACHE_ONLY = 0x2\n    KERB_RETRIEVE_TICKET_USE_CREDHANDLE = 0x4\n    KERB_RETRIEVE_TICKET_AS_KERB_CRED   = 0x8\n    KERB_RETRIEVE_TICKET_WITH_SEC_CRED  = 0x10 \n    KERB_RETRIEVE_TICKET_CACHE_TICKET   = 0x20\n    KERB_RETRIEVE_TICKET_MAX_LIFETIME   = 0x40\n} -Bitfield\n\n$KERB_ENCRYPTION_TYPE = psenum $Module KERB_ENCRYPTION_TYPE UInt32 @{\n        reserved0                         = 0\n        des_cbc_crc                       = 1\n        des_cbc_md4                       = 2\n        des_cbc_md5                       = 3\n        reserved1                         = 4\n        des3_cbc_md5                      = 5\n        reserved2                         = 6\n        des3_cbc_sha1                     = 7\n        dsaWithSHA1_CmsOID                = 9\n        md5WithRSAEncryption_CmsOID       = 10\n        sha1WithRSAEncryption_CmsOID      = 11\n        rc2CBC_EnvOID                     = 12\n        rsaEncryption_EnvOID              = 13\n        rsaES_OAEP_ENV_OID                = 14\n        des_ede3_cbc_Env_OID              = 15\n        des3_cbc_sha1_kd                  = 16\n        aes128_cts_hmac_sha1_96           = 17\n        aes256_cts_hmac_sha1_96           = 18\n        aes128_cts_hmac_sha256_128        = 19\n        aes256_cts_hmac_sha384_192        = 20\n        rc4_hmac                          = 23\n        rc4_hmac_exp                      = 24\n        camellia128_cts_cmac              = 25\n        camellia256_cts_cmac              = 26\n        subkey_keymaterial                = 65\n}\n\n$KERB_TICKET_FLAGS = psenum $Module KERB_TICKET_FLAGS UInt32 @{\n    reserved          = 2147483648\n    forwardable       = 0x40000000\n    forwarded         = 0x20000000\n    proxiable         = 0x10000000\n    proxy             = 0x08000000\n    may_postdate      = 0x04000000\n    postdated         = 0x02000000\n    invalid           = 0x01000000\n    renewable         = 0x00800000\n    initial           = 0x00400000\n    pre_authent       = 0x00200000\n    hw_authent        = 0x00100000\n    ok_as_delegate    = 0x00040000\n    name_canonicalize = 0x00010000\n    cname_in_pa_data  = 0x00040000\n    enc_pa_rep        = 0x00010000\n    reserved1         = 0x00000001\n} -Bitfield\n\n$LuidAttributes = psenum $Module LuidAttributes UInt32 @{\n    DISABLED                        = 0x00000000\n    SE_PRIVILEGE_ENABLED_BY_DEFAULT = 0x00000001\n    SE_PRIVILEGE_ENABLED            = 0x00000002\n    SE_PRIVILEGE_REMOVED            = 0x00000004\n    SE_PRIVILEGE_USED_FOR_ACCESS    = 2147483648\n} -Bitfield\n\n$MEMORY_PROTECTION = psenum $Module MEMORY_PROTECTION UInt32 @{\n    PAGE_NOACCESS          = 0x00000001\n    PAGE_READONLY          = 0x00000002\n    PAGE_READWRITE         = 0x00000004\n    PAGE_WRITECOPY         = 0x00000008\n    PAGE_EXECUTE           = 0x00000010\n    PAGE_EXECUTE_READ      = 0x00000020\n    PAGE_EXECUTE_READWRITE = 0x00000040\n    PAGE_EXECUTE_WRITECOPY = 0x00000080\n    PAGE_GUARD             = 0x00000100\n    PAGE_NOCACHE           = 0x00000200\n    PAGE_WRITECOMBINE      = 0x00000400\n    PAGE_TARGETS_NO_UPDATE = 0x40000000\n} -Bitfield\n\n$MEMORY_STATE = psenum $Module MEMORY_STATE UInt32 @{\n    MEM_COMMIT  = 0x1000\n    MEM_RESERVE = 0x2000\n    MEM_FREE    = 0x10000\n} -Bitfield\n\n$MEMORY_TYPE = psenum $Module MEMORY_TYPE UInt32 @{\n    MEM_PRIVATE = 0x20000\n    MEM_MAPPED  = 0x40000\n    MEM_IMAGE   = 0x1000000\n} -Bitfield\n\n$MIB_IPNET_TYPE = psenum $Module MIB_IPNET_TYPE UInt32 @{\n    OTHER   = 1\n    INVALID = 2\n    DYNAMIC = 3\n    STATIC  = 4\n}\n\n$PROCESS_ACCESS = psenum $Module PROCESS_ACCESS UInt32 @{\n    PROCESS_TERMINATE                 = 0x00000001\n    PROCESS_CREATE_THREAD             = 0x00000002\n    PROCESS_VM_OPERATION              = 0x00000008\n    PROCESS_VM_READ                   = 0x00000010\n    PROCESS_VM_WRITE                  = 0x00000020\n    PROCESS_DUP_HANDLE                = 0x00000040\n    PROCESS_CREATE_PROCESS            = 0x00000080\n    PROCESS_SET_QUOTA                 = 0x00000100\n    PROCESS_SET_INFORMATION           = 0x00000200\n    PROCESS_QUERY_INFORMATION         = 0x00000400\n    PROCESS_SUSPEND_RESUME            = 0x00000800\n    PROCESS_QUERY_LIMITED_INFORMATION = 0x00001000\n    DELETE                            = 0x00010000\n    READ_CONTROL                      = 0x00020000\n    WRITE_DAC                         = 0x00040000\n    WRITE_OWNER                       = 0x00080000\n    SYNCHRONIZE                       = 0x00100000\n    PROCESS_ALL_ACCESS                = 0x001f1ffb\n} -Bitfield\n\n$SC_SERVICE_TAG_QUERY_TYPE = psenum $Module SC_SERVICE_TAG_QUERY_TYPE UInt16 @{\n    ServiceNameFromTagInformation = 1\n    ServiceNamesReferencingModuleInformation = 2\n    ServiceNameTagMappingInformation = 3\n}\n\n$SE_GROUP = psenum $Module SE_GROUP UInt32 @{\n    DISABLED           = 0x00000000\n    MANDATORY          = 0x00000001\n    ENABLED_BY_DEFAULT = 0x00000002\n    ENABLED            = 0x00000004\n    OWNER              = 0x00000008\n    USE_FOR_DENY_ONLY  = 0x00000010\n    INTEGRITY          = 0x00000020\n    INTEGRITY_ENABLED  = 0x00000040\n    RESOURCE           = 0x20000000\n    LOGON_ID           = 3221225472\n} -Bitfield\n\n$SE_PRIVILEGE = psenum $Module SE_PRIVILEGE UInt32 @{\n    DISABLED           = 0x00000000\n    ENABLED_BY_DEFAULT = 0x00000001\n    ENABLED            = 0x00000002\n    REMOVED            = 0x00000004\n    USED_FOR_ACCESS    = 2147483648\n} -Bitfield\n\n$SECPKG_FLAG = psenum $Module SECPKG_FLAG UInt32 @{\n    INTEGRITY                = 0x1\n    PRIVACY                  = 0x2\n    TOKEN_ONLY               = 0x4\n    DATAGRAM                 = 0x8\n    CONNECTION               = 0x10\n    MULTI_REQUIRED           = 0x20\n    CLIENT_ONLY              = 0x40\n    EXTENDED_ERROR           = 0x80\n    IMPERSONATION            = 0x100\n    ACCEPT_WIN32_NAME        = 0x200\n    STREAM                   = 0x400\n    NEGOTIABLE               = 0X800\n    GSS_COMPATIBLE           = 0x1000\n    LOGON                    = 0x2000\n    ASCII_BUFFERS            = 0x4000\n    FRAGMENT                 = 0x8000\n    MUTUAL_AUTH              = 0x10000\n    DELEGATION               = 0x20000\n    READONLY_WITH_CHECKSUM   = 0x40000\n    RESTRICTED_TOKENS        = 0x80000\n    NEGO_EXTENDER            = 0x00100000\n    NEGOTIABLE2              = 0x00200000\n    APPCONTAINER_PASSTHROUGH = 0x00400000\n    APPCONTAINER_CHECKS      = 0x00800000\n\n    #SECPKG_CALLFLAGS_APPCONTAINER = 0x00000001\n    #SECPKG_CALLFLAGS_AUTHCAPABLE = 0x00000002\n    #SECPKG_CALLFLAGS_FORCE_SUPPLIED = 0x00000004\n} -Bitfield\n\n$SECURITY_IMPERSONATION_LEVEL = psenum $Module SECURITY_IMPERSONATION_LEVEL UInt32 @{\n    SecurityAnonymous      = 0\n    SecurityIdentification = 1\n    SecurityImpersonation  = 2\n    SecurityDelegation     = 3\n}\n\n$SECURITY_LOGON_TYPE = psenum $Module SECURITY_LOGON_TYPE UInt32 @{\n    Interactive = 2\n    Network     = 3\n    Batch       = 4\n    Service     = 5\n    Proxy       = 6\n    Unlock      = 7\n    NetworkCleartext = 8\n    NewCredentials = 9\n    RemoteInteractive = 10\n    CachedInteractive = 11\n    CachedRemoteInteractive = 12\n    CachedUnlock = 13\n}\n\n$TAG_INFO_LEVEL = psenum $Module TAG_INFO_LEVEL UInt16 @{\n    eTagInfoLevelNameFromTag = 1\n    eTagInfoLevelNamesReferencingModule = 2\n    eTagInfoLevelNameTagMapping = 3\n    eTagInfoLevelMax = 4\n}\n\n$TCP_STATE = psenum $Module TCP_STATE UInt16 @{\n    CLOSED = 1\n    LISTENING = 2\n    SYN_SENT = 3\n    SYN_RECEIVED = 4\n    ESTABLISHED = 5\n    FIN_WAIT1 = 6\n    FIN_WAIT2 = 7\n    CLOSE_WAIT = 8\n    CLOSING = 9\n    LAST_ACK = 10\n    TIME_WAIT = 11\n    DELETE_TCB = 12\n}\n\n$TCP_TABLE_CLASS = psenum $Module TCP_TABLE_CLASS UInt16 @{\n    TCP_TABLE_BASIC_LISTENER = 0\n    TCP_TABLE_BASIC_CONNECTIONS = 1\n    TCP_TABLE_BASIC_ALL = 2\n    TCP_TABLE_OWNER_PID_LISTENER = 3\n    TCP_TABLE_OWNER_PID_CONNECTIONS = 4\n    TCP_TABLE_OWNER_PID_ALL = 5\n    TCP_TABLE_OWNER_MODULE_LISTENER = 6\n    TCP_TABLE_OWNER_MODULE_CONNECTIONS = 7\n    TCP_TABLE_OWNER_MODULE_ALL = 8\n}\n\n$TH32CS = psenum $Module TH32CS UInt32 @{\n    SNAPHEAPLIST = 0x00000001\n    SNAPPROCESS  = 0x00000002\n    SNAPTHREAD   = 0x00000004\n    SNAPMODULE   = 0x00000008\n    SNAPALL      = 0x0000000F\n    SNAPMODULE32 = 0x00000010\n    INHERIT      = 2147483648\n} -Bitfield\n\n$THREAD_ACCESS = psenum $Module THREAD_ACCESS UInt32 @{\n    THREAD_TERMINATE                 = 0x00000001\n    THREAD_SUSPEND_RESUME            = 0x00000002\n    THREAD_GET_CONTEXT               = 0x00000008\n    THREAD_SET_CONTEXT               = 0x00000010\n    THREAD_SET_INFORMATION           = 0x00000020\n    THREAD_QUERY_INFORMATION         = 0x00000040\n    THREAD_SET_THREAD_TOKEN          = 0x00000080\n    THREAD_IMPERSONATE               = 0x00000100\n    THREAD_DIRECT_IMPERSONATION      = 0x00000200\n    THREAD_SET_LIMITED_INFORMATION   = 0x00000400\n    THREAD_QUERY_LIMITED_INFORMATION = 0x00000800\n    DELETE                           = 0x00010000\n    READ_CONTROL                     = 0x00020000\n    WRITE_DAC                        = 0x00040000\n    WRITE_OWNER                      = 0x00080000\n    SYNCHRONIZE                      = 0x00100000\n    THREAD_ALL_ACCESS                = 0x001f0ffb\n} -Bitfield\n\n$THREADINFOCLASS = psenum $Module THREADINFOCLASS UInt32 @{\n\tThreadBasicInformation          = 0x00\n\tThreadTimes                     = 0x01\n\tThreadPriority                  = 0x02\n\tThreadBasePriority              = 0x03\n\tThreadAffinityMask              = 0x04\n\tThreadImpersonationToken        = 0x05\n\tThreadDescriptorTableEntry      = 0x06\n\tThreadEnableAlignmentFaultFixup = 0x07\n\tThreadEventPair_Reusable        = 0x08\n\tThreadQuerySetWin32StartAddress = 0x09\n\tThreadZeroTlsCell               = 0x0A\n\tThreadPerformanceCount          = 0x0B\n\tThreadAmILastThread             = 0x0C\n\tThreadIdealProcessor            = 0x0D\n\tThreadPriorityBoost             = 0x0E\n\tThreadSetTlsArrayAddress        = 0x0F\n\tThreadIsIoPending               = 0x10\n\tMaxThreadInfoClass              = 0x11\n}\n\n$TOKEN_ACCESS = psenum $Module TOKEN_ACCESS UInt32 @{\n    TOKEN_DUPLICATE          = 0x00000002\n    TOKEN_IMPERSONATE        = 0x00000004\n    TOKEN_QUERY              = 0x00000008\n    TOKEN_QUERY_SOURCE       = 0x00000010\n    TOKEN_ADJUST_PRIVILEGES  = 0x00000020\n    TOKEN_ADJUST_GROUPS      = 0x00000040\n    TOKEN_ADJUST_DEFAULT     = 0x00000080\n    TOKEN_ADJUST_SESSIONID   = 0x00000100\n    DELETE                   = 0x00010000\n    READ_CONTROL             = 0x00020000\n    WRITE_DAC                = 0x00040000\n    WRITE_OWNER              = 0x00080000\n    SYNCHRONIZE              = 0x00100000\n    STANDARD_RIGHTS_REQUIRED = 0x000F0000\n    TOKEN_ALL_ACCESS         = 0x001f01ff\n} -Bitfield\n\n$TOKEN_ELEVATION_TYPE = psenum $Module TOKEN_ELEVATION_TYPE UInt32 @{ \n    TokenElevationTypeDefault = 1\n    TokenElevationTypeFull    = 2\n    TokenElevationTypeLimited = 3\n}\n\n$TOKEN_INFORMATION_CLASS = psenum $Module TOKEN_INFORMATION_CLASS UInt16 @{ \n    TokenUser                            = 1\n    TokenGroups                          = 2\n    TokenPrivileges                      = 3\n    TokenOwner                           = 4\n    TokenPrimaryGroup                    = 5\n    TokenDefaultDacl                     = 6\n    TokenSource                          = 7\n    TokenType                            = 8\n    TokenImpersonationLevel              = 9\n    TokenStatistics                      = 10\n    TokenRestrictedSids                  = 11\n    TokenSessionId                       = 12\n    TokenGroupsAndPrivileges             = 13\n    TokenSessionReference                = 14\n    TokenSandBoxInert                    = 15\n    TokenAuditPolicy                     = 16\n    TokenOrigin                          = 17\n    TokenElevationType                   = 18\n    TokenLinkedToken                     = 19\n    TokenElevation                       = 20\n    TokenHasRestrictions                 = 21\n    TokenAccessInformation               = 22\n    TokenVirtualizationAllowed           = 23\n    TokenVirtualizationEnabled           = 24\n    TokenIntegrityLevel                  = 25\n    TokenUIAccess                        = 26\n    TokenMandatoryPolicy                 = 27\n    TokenLogonSid                        = 28\n    TokenIsAppContainer                  = 29\n    TokenCapabilities                    = 30\n    TokenAppContainerSid                 = 31\n    TokenAppContainerNumber              = 32\n    TokenUserClaimAttributes             = 33\n    TokenDeviceClaimAttributes           = 34\n    TokenRestrictedUserClaimAttributes   = 35\n    TokenRestrictedDeviceClaimAttributes = 36\n    TokenDeviceGroups                    = 37\n    TokenRestrictedDeviceGroups          = 38\n    TokenSecurityAttributes              = 39\n    TokenIsRestricted                    = 40\n    MaxTokenInfoClass                    = 41\n}\n\n$TOKENMANDATORYPOLICY = psenum $Module TOKENMANDATORYPOLICY UInt32 @{\n    OFF                    = 0x0\n    NO_WRITE_UP            = 0x1\n    POLICY_NEW_PROCESS_MIN = 0x2\n    POLICY_VALID_MASK      = 0x3\n}\n\n$TOKEN_TYPE = psenum $Module TOKEN_TYPE UInt32 @{\n    TokenPrimary       = 1\n    TokenImpersonation = 2\n}\n\n$UDP_TABLE_CLASS = psenum $Module UDP_TABLE_CLASS UInt16 @{\n    UDP_TABLE_BASIC = 0\n    UDP_TABLE_OWNER_PID = 1\n    UDP_TABLE_OWNER_MODULE = 2\n}\n#endregion Enums\n\n#region Structs\n$ACL = struct $Module ACL @{\n    AclRevision = field 0 Byte\n    Sbz1        = field 1 Byte\n    AclSize     = field 2 UInt16\n    AceCount    = field 3 UInt16\n    Sbz2        = field 4 UInt16\n}\n\n$LUID = struct $Module LUID @{\n    LowPart  = field 0 UInt32\n    HighPart = field 1 Int32\n}\n\n$LUID_AND_ATTRIBUTES = struct $Module LUID_AND_ATTRIBUTES @{\n    Luid       = field 0 $LUID\n    Attributes = field 1 $SE_PRIVILEGE\n}\n\n$LSA_LAST_INTER_LOGON_INFO = struct $Module LSA_LAST_INTER_LOGON_INFO @{\n    LastSuccessfulLogon                        = field 0 Int64\n    LastFailedLogon                            = field 1 Int64\n    FailedAttemptCountSinceLastSuccessfulLogon = field 2 UInt64\n}\n\n$LSA_STRING = struct $Module LSA_STRING @{\n    Length = field 0 UInt16\n    MaximumLength = field 1 UInt16\n    Buffer = field 2 IntPtr\n}\n\n$LSA_UNICODE_STRING = struct $Module LSA_UNICODE_STRING @{\n    Length        = field 0 UInt16\n    MaximumLength = field 1 UInt16\n    Buffer        = field 2 IntPtr\n}\n\n$MEMORY_BASIC_INFORMATION = struct $Module MEMORY_BASIC_INFORMATION @{\n    BaseAddress       = field 0 UIntPtr\n    AllocationBase    = field 1 UIntPtr\n    AllocationProtect = field 2 $MEMORY_PROTECTION\n    RegionSize        = field 3 UIntPtr\n    State             = field 4 $MEMORY_STATE\n    Protect           = field 5 $MEMORY_PROTECTION\n    Type              = field 6 $MEMORY_TYPE\n}\n\n$MIB_IPNETROW = struct $Module MIB_IPNETROW @{\n    dwIndex = field 0 UInt32\n    dwPhysAddrLen = field 1 UInt32\n    bPhysAddr = field 2 byte[] -MarshalAs @('ByValArray', 6)\n    dwAddr = field 3 UInt32\n    dwType = field 4 UInt32\n}\n\n$MIB_UDPROW_OWNER_MODULE = struct $Module MIB_UDPROW_OWNER_MODULE @{\n    LocalAddr        = field 0 UInt32 0\n    LocalPort        = field 1 UInt32 4\n    OwningPid        = field 2 UInt32 8\n    CreateTimestamp  = field 3 UInt64 16\n    SpecificPortBind = field 4 UInt32 24  # Union\n    Flags            = field 5 UInt32 24\n    OwningModuleInfo = field 6 UInt64[] -MarshalAs @('ByValArray', 16) 32\n} -ExplicitLayout\n\n$MIB_UDP6ROW_OWNER_MODULE = struct $Module MIB_UDP6ROW_OWNER_MODULE @{\n    LocalAddr        = field 0 Byte[] -MarshalAs @('ByValArray', 16) 0\n    LocalScopeId   = field 1 UInt32 16\n    LocalPort      = field 2 UInt32 20\n    OwningPid      = field 3 UInt32 24\n    CreateTimestamp  = field 4 UInt64 32\n    SpecificPortBind = field 5 UInt32 40  # Union\n    Flags            = field 6 UInt32 40\n    OwningModuleInfo = field 7 UInt64[] -MarshalAs @('ByValArray', 16) 48\n} -ExplicitLayout\n\n$MIB_UDPTABLE_OWNER_MODULE = struct $Module MIB_UDPTABLE_OWNER_MODULE @{\n    NumEntries = field 0 UInt32\n    Table      = field 1 $MIB_UDPROW_OWNER_MODULE\n}\n\n$MIB_UDP6TABLE_OWNER_MODULE = struct $Module MIB_UDP6TABLE_OWNER_MODULE @{\n    NumEntries = field 0 UInt32\n    Table      = field 1 $MIB_UDPROW_OWNER_MODULE\n}\n\n$MIB_TCPROW_OWNER_MODULE = struct $Module MIB_TCPROW_OWNER_MODULE @{\n    State           = field 0 $TCP_STATE\n    LocalAddr       = field 1 UInt32\n    LocalPort       = field 2 UInt32\n    RemoteAddr      = field 3 UInt32\n    RemotePort      = field 4 UInt32\n    OwningPid       = field 5 UInt32\n    CreateTimestamp = field 6 UInt64\n    OwningModuleInfo = field 7 UInt64[] -MarshalAs @('ByValArray', 16)\n}\n\n$MIB_TCP6ROW_OWNER_MODULE = struct $Module MIB_TCP6ROW_OWNER_MODULE @{\n    LocalAddr        = field 0 Byte[] -MarshalAs @('ByValArray', 16)\n    LocalScopeId     = field 1 UInt32\n    LocalPort        = field 2 UInt32\n    RemoteAddr       = field 3 Byte[] -MarshalAs @('ByValArray', 16)\n    RemoteScopeId    = field 4 UInt32\n    RemotePort       = field 5 UInt32\n    State            = field 6 $TCP_STATE\n    OwningPid        = field 7 UInt32\n    CreateTimestamp  = field 8 UInt64\n    OwningModuleInfo = field 9 UInt64[] -MarshalAs @('ByValArray', 16)\n}\n\n$MIB_TCPTABLE_OWNER_MODULE = struct $Module MIB_TCPTABLE_OWNER_MODULE @{\n    NumEntries = field 0 UInt32\n    Table      = field 1 $MIB_TCPROW_OWNER_MODULE\n}\n\n$MIB_TCP6TABLE_OWNER_MODULE = struct $Module MIB_TCP6TABLE_OWNER_MODULE @{\n    NumEntries = field 0 UInt32\n    Table      = field 1 $MIB_TCP6ROW_OWNER_MODULE\n}\n\n$KERB_CRYPTO_KEY = struct $Module KERB_CRYPTO_KEY @{\n    KeyType = field 0 Int32\n    Length = field 1 Int32\n    Value = field 2 IntPtr\n}\n\n$KERB_EXTERNAL_NAME = struct $Module KERB_EXTERNAL_NAME @{\n    NameType = field 0 Int16\n    NameCount = field 1 UInt16\n    Names = field 2 $LSA_UNICODE_STRING\n}\n\n$KERB_EXTERNAL_TICKET = struct $Module KERB_EXTERNAL_TICKET @{\n    ServiceName = field 0 IntPtr\n    TargetName = field 1 IntPtr\n    ClientName = field 2 IntPtr\n    DomainName = field 3 $LSA_UNICODE_STRING\n    TargetDomainName = field 4 $LSA_UNICODE_STRING\n    AltTargetDomainName = field 5 $LSA_UNICODE_STRING\n    SessionKey = field 6 $KERB_CRYPTO_KEY\n    TicketFlags = field 7 UInt32\n    Flags = field 8 UInt32\n    KeyExpirationTime = field 9 Int64\n    StartTime = field 10 Int64\n    EndTime = field 11 Int64\n    RenewUntil = field 12 Int64\n    TimeSkew = field 13 Int64\n    EncodedTicketSize = field 14 Int32\n    EncodedTicket = field 15 IntPtr\n}\n\n$KERB_TICKET_CACHE_INFO = struct $Module KERB_TICKET_CACHE_INFO @{\n    ServerName = field 0 $LSA_UNICODE_STRING\n    RealmName = field 1 $LSA_UNICODE_STRING\n    StartTime = field 2 Int64\n    EndTime = field 3 Int64\n    RenewTime = field 4 Int64\n    EncryptionType = field 5 Int32\n    TicketFlags = field 6 UInt32\n}\n\n$KERB_QUERY_TKT_CACHE_REQUEST = struct $Module KERB_QUERY_TKT_CACHE_REQUEST @{\n    MessageType = field 0 $KERB_PROTOCOL_MESSAGE_TYPE\n    LogonId = field 1 $LUID\n}\n\n$KERB_QUERY_TKT_CACHE_RESPONSE = struct $Module KERB_QUERY_TKT_CACHE_RESPONSE @{\n    MessageType = field 0 $KERB_PROTOCOL_MESSAGE_TYPE\n    CountOfTickets = field 1 UInt32\n    Tickets = field 2 $KERB_TICKET_CACHE_INFO.MakeArrayType() -MarshalAs @('ByValArray', 1)\n}\n\n$SecHandle = struct $Module SecHandle @{\n    dwLower = field 0 IntPtr       \n    dwUpper = field 1 IntPtr\n}\n\n$KERB_RETRIEVE_TKT_REQUEST = struct $Module KERB_RETRIEVE_TKT_REQUEST @{\n    MessageType = field 0 $KERB_PROTOCOL_MESSAGE_TYPE\n    LogonId = field 1 $LUID\n    TargetName = field 2 $LSA_UNICODE_STRING\n    TicketFlags = field 3 UInt64\n    CacheOptions = field 4 $KERB_CACHE_OPTIONS\n    EncryptionType = field 5 Int64\n    CredentialsHandle = field 6 $SecHandle\n}\n\n$KERB_RETRIEVE_TKT_RESPONSE = struct $Module KERB_RETRIEVE_TKT_RESPONSE @{\n    Ticket = field 0 $KERB_EXTERNAL_TICKET\n}\n\n$SC_SERVICE_TAG_QUERY = struct $Module SC_SERVICE_TAG_QUERY @{\n    ProcessId = field 0 UInt32\n    ServiceTag = field 1 UInt32\n    Unknown = field 2 UInt32\n    Buffer = field 3 IntPtr\n}\n\n$SECURITY_LOGON_SESSION_DATA = struct $Module SECURITY_LOGON_SESSION_DATA @{\n    Size                  = field 0 UInt32\n    LogonId               = field 1 $LUID\n    Username              = field 2 $LSA_UNICODE_STRING\n    LogonDomain           = field 3 $LSA_UNICODE_STRING\n    AuthenticationPackage = field 4 $LSA_UNICODE_STRING\n    LogonType             = field 5 UInt32\n    Session               = field 6 UInt32\n    PSiD                  = field 7 IntPtr\n    LogonTime             = field 8 UInt64\n    LogonServer           = field 9 $LSA_UNICODE_STRING\n    DnsDomainName         = field 10 $LSA_UNICODE_STRING\n    Upn                   = field 11 $LSA_UNICODE_STRING\n    UserFlags             = field 12 UInt64\n    LastLogonInfo         = field 13 $LSA_LAST_INTER_LOGON_INFO\n    LogonScript           = field 14 $LSA_UNICODE_STRING\n    ProfilePath           = field 15 $LSA_UNICODE_STRING\n    HomeDirectory         = field 16 $LSA_UNICODE_STRING\n    HomeDirectoryDrive    = field 17 $LSA_UNICODE_STRING\n    LogoffTime            = field 18 Int64\n    KickOffTime           = field 19 Int64\n    PasswordLastSet       = field 20 Int64\n    PasswordCanChange     = field 21 Int64\n    PasswordMustChange    = field 22 Int64\n}\n\n$SecPkgInfo = struct $Module SecPkgInfo @{\n    Capabilities = field 0 $SECPKG_FLAG\n    Version = field 1 UInt16\n    RPCID = field 2 UInt16\n    MaxToken = field 3 UInt32\n    Name = field 4 IntPtr\n    Comment = field 5 IntPtr\n}\n\n$SID_AND_ATTRIBUTES = struct $Module SID_AND_ATTRIBUTES @{\n    Sid        = field 0 IntPtr\n    Attributes = field 1 $SE_GROUP\n} -PackingSize Size8\n\n$THREADENTRY32 = struct $Module THREADENTRY32 @{\n    dwSize             = field 0 UInt32\n    cntUsage           = field 1 UInt32\n    th32ThreadID       = field 2 UInt32\n    th32OwnerProcessID = field 3 UInt32\n    tpBasePri          = field 4 UInt32\n    tpDeltaPri         = field 5 UInt32\n    dwFlags            = field 6 UInt32\n}\n\n$TOKEN_APPCONTAINER_INFORMATION = struct $Module TOKEN_APPCONSTAINER_INFORMATION @{\n    TokenAppContainer = field 0 IntPtr\n}\n\n$TOKEN_DEFAULT_DACL = struct $Module TOKEN_DEFAULT_DACL @{\n    DefaultDacl = field 0 $ACL\n}\n\n$TOKEN_ELEVATION = struct $Module TOKEN_ELEVATION @{\n    TokenIsElevated = field 0 UInt32\n}\n\n$TOKEN_GROUPS = struct $Module TOKEN_GROUPS @{\n    GroupCount = field 0 UInt32\n    Groups     = field 1 $SID_AND_ATTRIBUTES.MakeArrayType() -MarshalAs ('ByValArray', 50)\n}\n\n$TOKEN_GROUPS_AND_PRIVILEGES = struct $Module TOKEN_GROUPS_AND_PRIVILEGES @{\n    SidCount            = field 0 UInt32\n    SidLength           = field 1 UInt32\n    Sids                = field 2 IntPtr\n    RestrictedSidCount  = field 3 UInt32\n    RestrictedSidLength = field 4 UInt32\n    RestrictedSids      = field 5 IntPtr\n    PrivilegeCount      = field 6 UInt32\n    PrivilegeLength     = field 7 UInt32\n    Privileges          = field 8 IntPtr\n    AuthenticationId    = field 9 $LUID\n}\n\n$TOKEN_LINKED_TOKEN = struct $Module TOKEN_LINKED_TOKEN @{\n    LinkedToken = field 0 IntPtr\n}\n\n$TOKEN_MANDATORY_LABEL = struct $Module TOKEN_MANDATORY_LABEL @{\n    Label = field 0 $SID_AND_ATTRIBUTES\n}\n\n$TOKEN_MANDATORY_POLICY = struct $Module TOKEN_MANDATORY_POLICY @{\n    Policy = field 0 $TOKENMANDATORYPOLICY\n}\n\n$TOKEN_OWNER = struct $Module TOKEN_OWNER @{\n    Owner = field 0 IntPtr\n}\n\n$TOKEN_PRIVILEGES = struct $Module TOKEN_PRIVILEGES @{\n    PrivilegeCount = field 0 UInt32\n    Privileges     = field 1  $LUID_AND_ATTRIBUTES.MakeArrayType() -MarshalAs @('ByValArray', 50)\n}\n\n$TOKEN_SOURCE = struct $Module TOKEN_SOURCE @{\n    SourceName       = field 0 string\n    SourceIdentifier = field 1 $LUID\n}\n\n$TOKEN_STATISTICS = struct $Module TOKEN_STATISTICS @{\n    TokenId            = field 0 $LUID\n    AuthenticationId   = field 1 $LUID\n    ExpirationTime     = field 2 UInt64\n    TokenType          = field 3 $TOKEN_TYPE\n    ImpersonationLevel = field 4 $SECURITY_IMPERSONATION_LEVEL\n    DynamicCharged     = field 5 UInt32\n    DynamicAvailable   = field 6 UInt32\n    GroupCount         = field 7 UInt32\n    PrivilegeCount     = field 8 UInt32\n    ModifiedId         = field 9 $LUID\n}\n\n$TOKEN_USER = struct $Module TOKEN_USER @{\n    User = field 0 $SID_AND_ATTRIBUTES\n}\n#endregion Structs\n\n#region Function Definitions\n$FunctionDefinitions = @(\n    (func kernel32 CloseHandle ([bool]) @(\n        [IntPtr] #_In_ HANDLE hObject\n    ) -EntryPoint CloseHandle -SetLastError),\n    (func advapi32 ConvertSidToStringSid ([bool]) @(\n        [IntPtr],                #_In_  PSID   Sid\n        [IntPtr].MakeByRefType() #_Out_ LPTSTR *StringSid\n    ) -EntryPoint ConvertSidToStringSid -SetLastError),\n    (func kernel32 CreateToolhelp32Snapshot ([IntPtr]) @(\n        [UInt32], #_In_ DWORD dwFlags\n        [UInt32]  #_In_ DWORD th32ProcessID\n    ) -EntryPoint CreateToolhelp32Snapshot -SetLastError),\n    (func advapi32 DuplicateToken ([bool]) @(\n        [IntPtr],                #_In_  HANDLE                       ExistingTokenHandle,\n        [UInt32],                #_In_  SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,\n        [IntPtr].MakeByRefType() #_Out_ PHANDLE                      DuplicateTokenHandle\n    ) -EntryPoint DuplicateToken -SetLastError),\n    (func secur32 EnumerateSecurityPackages ([UInt32]) @(\n        [UInt32].MakeByRefType(), #_In_ PULONG      pcPackages\n        [IntPtr].MakeByRefType()  #_In_ PSecPkgInfo *ppPackageInfo\n    ) -EntryPoint EnumerateSecurityPackages),\n    (func secur32 FreeContextBuffer ([UInt32]) @(\n          [IntPtr] #_In_ PVOID pvContextBuffer\n    ) -EntryPoint FreeContextBuffer),\n    (func iphlpapi GetExtendedTcpTable ([UInt32]) @([IntPtr], [Int32].MakeByRefType(), [Bool], [Int32], [Int32], [Int32]) -EntryPoint GetExtendedTcpTable),\n    (func iphlpapi GetExtendedUdpTable ([UInt32]) @([IntPtr], [Int32].MakeByRefType(), [Bool], [Int32], [Int32], [Int32]) -EntryPoint GetExtendedUdpTable),\n    (func iphlpapi GetIpNetTable ([Int32]) @(\n        [IntPtr],                 #_Out_   PMIB_IPNETTABLE pIpNetTable\n        [Int32].MakeByRefType(),  #_Inout_ PULONG          pdwSize\n        [bool]                    #_In_    BOOL            bOrder\n    ) -EntryPoint GetIpNetTable),\n    (func advapi32 GetTokenInformation ([bool]) @(\n        [IntPtr],                #_In_      HANDLE                  TokenHandle\n        [Int32],                 #_In_      TOKEN_INFORMATION_CLASS TokenInformationClass\n        [IntPtr],                #_Out_opt_ LPVOID                  TokenInformation\n        [UInt32],                #_In_      DWORD                   TokenInformationLength\n        [UInt32].MakeByRefType() #_Out_     PDWORD                  ReturnLength\n    ) -EntryPoint GetTokenInformation -SetLastError),\n    (func kernel32 GlobalGetAtomName ([UInt32]) @(\n        [UInt16], #_In_  ATOM   nAtom\n        [IntPtr], #_Out_ LPTSTR lpBuffer\n        [UInt32]  #_In_  int    nSize\n    ) -EntryPoint GlobalGetAtomName -SetLastError),\n    (func advapi32 ImpersonateLoggedOnUser ([bool]) @(\n        [IntPtr] #_In_ HANDLE hToken\n    ) -EntryPoint ImpersonateLoggedOnUser -SetLastError),\n    (func advapi32 I_QueryTagInformation ([UInt32]) @([IntPtr], $SC_SERVICE_TAG_QUERY_TYPE, $SC_SERVICE_TAG_QUERY.MakeByRefType()) -EntryPoint I_QueryTagInformation),\n    (func advapi32 LookupPrivilegeName ([bool]) @(\n        [string],                    #_In_opt_  LPCTSTR lpSystemName\n        [IntPtr],                    #_In_      PLUID   lpLuid\n        [sYstem.Text.StringBuilder], #_Out_opt_ LPTSTR  lpName\n        [UInt32].MakeByRefType()     #_Inout_   LPDWORD cchName\n    ) -EntryPoint LookupPrivilegeName -SetLastError),\n    (func advapi32 LookupPrivilegeDisplayName ([bool]) @(\n        [string],                    #_In_opt_  LPCTSTR lpSystemName,\n        [string],                    #_In_      LPCTSTR lpName,\n        [System.Text.StringBuilder], #_Out_opt_ LPTSTR  lpDisplayName,\n        [UInt32].MakeByRefType(),    #_Inout_   LPDWORD cchDisplayName,\n        [UInt32].MakeByRefType()     #_Out_     LPDWORD lpLanguageId\n    ) -EntryPoint LookupPrivilegeDisplayName -SetLastError),\n    (func secur32 LsaCallAuthenticationPackage_KERB_QUERY_TKT_CACHE ([UInt32]) @(\n        [IntPtr],                                      #_In_  HANDLE    LsaHandle\n        [UInt64],                                      #_In_  ULONG     AuthenticationPackage\n        $KERB_QUERY_TKT_CACHE_REQUEST.MakeByRefType(), #_In_  PVOID     ProtocolSubmitBuffer\n        [UInt64],                                      #_In_  ULONG     SubmitBufferLength\n        [IntPtr].MakeByRefType(),#_Out_ PVOID     *ProtocolReturnBuffer\n        [UInt64].MakeByRefType(),                      #_Out_ PULONG    *ReturnBufferLength\n        [UInt32].MakeByRefType()                       #_Out_ PNTSTATUS ProtocolStatus\n    ) -EntryPoint LsaCallAuthenticationPackage),\n    (func secur32 LsaCallAuthenticationPackage_KERB_RETRIEVE_TKT ([UInt32]) @(\n        [IntPtr],                                   #_In_  HANDLE    LsaHandle\n        [UInt64],                                   #_In_  ULONG     AuthenticationPackage\n        $KERB_RETRIEVE_TKT_REQUEST.MakeByRefType(), #_In_  PVOID     ProtocolSubmitBuffer\n        [UInt64],                                   #_In_  ULONG     SubmitBufferLength\n        [IntPtr].MakeByRefType(),#_Out_ PVOID     *ProtocolReturnBuffer\n        [UInt64].MakeByRefType(),                   #_Out_ PULONG    *ReturnBufferLength\n        [UInt32].MakeByRefType()                    #_Out_ PNTSTATUS ProtocolStatus\n    ) -EntryPoint LsaCallAuthenticationPackage),\n    (func secur32 LsaConnectUntrusted ([UInt32]) @(\n        [IntPtr].MakeByRefType()                #_Out_ PHANDLE LsaHandle\n    ) -EntryPoint LsaConnectUntrusted),\n    (func secur32 LsaDeregisterLogonProcess ([UInt32]) @(\n        [IntPtr]                                #_In_ HANDLE LsaHandle\n    ) -EntryPoint LsaDeregisterLogonProcess),\n    (func secur32 LsaEnumerateLogonSessions ([UInt32]) @(\n        [UInt64].MakeByRefType(), #_Out_ PULONG LogonSessionCount,\n        [IntPtr].MakeByRefType()  #_Out_ PLUID  *LogonSessionList\n    ) -EntryPoint LsaEnumerateLogonSessions),\n    (func secur32 LsaFreeReturnBuffer ([UInt32]) @(\n        [IntPtr] #_In_ PVOID Buffer\n    ) -EntryPoint LsaFreeReturnBuffer),\n    (func secur32 LsaGetLogonSessionData ([UInt32]) @(\n        [IntPtr],                #_In_  PLUID                        LogonId,\n        [IntPtr].MakeByRefType() #_Out_ PSECURITY_LOGON_SESSION_DATA *ppLogonSessionData\n    ) -EntryPoint LsaGetLogonSessionData),\n    (func secur32 LsaLookupAuthenticationPackage ([UInt32]) @(\n        [IntPtr],                    #_In_  HANDLE      LsaHandle,\n        $LSA_STRING.MakeByRefType(), #_In_  PLSA_STRING PackageName,\n        [UInt64].MakeByRefType()     #_Out_ PULONG      AuthenticationPackage\n    ) -EntryPoint LsaLookupAuthenticationPackage),\n    (func advapi32 LsaNtStatusToWinError ([UInt64]) @(\n        [UInt32] #_In_ NTSTATUS Status\n    ) -EntryPoint LsaNtStatusToWinError),\n    (func secur32 LsaRegisterLogonProcess ([UInt32]) @(\n        $LSA_STRING.MakeByRefType(), #_In_  PLSA_STRING           LogonProcessName,\n        [IntPtr].MakeByRefType(),    #_Out_ PHANDLE               LsaHandle,\n        [UInt64].MakeByRefType()     #_Out_ PLSA_OPERATIONAL_MODE SecurityMode\n    ) -EntryPoint LsaRegisterLogonProcess),\n    (func ntdll NtQueryInformationThread ([Int32]) @(\n        [IntPtr], #_In_      HANDLE          ThreadHandle,\n        [Int32],  #_In_      THREADINFOCLASS ThreadInformationClass,\n        [IntPtr], #_Inout_   PVOID           ThreadInformation,\n        [Int32],  #_In_      ULONG           ThreadInformationLength,\n        [IntPtr]  #_Out_opt_ PULONG          ReturnLength\n    ) -EntryPoint NtQueryInformationThread),\n    (func kernel32 OpenProcess ([IntPtr]) @(\n        [UInt32], #_In_ DWORD dwDesiredAccess\n        [bool],   #_In_ BOOL  bInheritHandle\n        [UInt32]  #_In_ DWORD dwProcessId\n    ) -EntryPoint OpenProcess -SetLastError),\n    (func advapi32 OpenProcessToken ([bool]) @(\n        [IntPtr],                #_In_  HANDLE  ProcessHandle\n        [UInt32],                #_In_  DWORD   DesiredAccess\n        [IntPtr].MakeByRefType() #_Out_ PHANDLE TokenHandle\n    ) -EntryPoint OpenProcessToken -SetLastError),\n    (func kernel32 OpenThread ([IntPtr]) @(\n        [UInt32], #_In_ DWORD dwDesiredAccess\n        [bool],   #_In_ BOOL  bInheritHandle\n        [UInt32]  #_In_ DWORD dwThreadId\n    ) -EntryPoint OpenThread -SetLastError),\n    (func advapi32 OpenThreadToken ([bool]) @(\n      [IntPtr],                #_In_  HANDLE  ThreadHandle\n      [UInt32],                #_In_  DWORD   DesiredAccess\n      [bool],                  #_In_  BOOL    OpenAsSelf\n      [IntPtr].MakeByRefType() #_Out_ PHANDLE TokenHandle\n    ) -EntryPoint OpenThreadToken -SetLastError),\n    (func kernel32 QueryFullProcessImageName ([bool]) @(\n      [IntPtr],                    #_In_    HANDLE hProcess\n      [UInt32],                    #_In_    DWORD  dwFlags,\n      [System.Text.StringBuilder], #_Out_   LPTSTR lpExeName,\n      [UInt32].MakeByRefType()     #_Inout_ PDWORD lpdwSize\n    ) -EntryPoint QueryFullProcessImageName -SetLastError),    \n    (func kernel32 ReadProcessMemory ([Bool]) @(\n        [IntPtr],               # _In_ HANDLE hProcess\n        [IntPtr],               # _In_ LPCVOID lpBaseAddress\n        [Byte[]],               # _Out_ LPVOID  lpBuffer\n        [Int32],                # _In_ SIZE_T nSize\n        [Int32].MakeByRefType() # _Out_ SIZE_T *lpNumberOfBytesRead\n    ) -EntryPoint ReadProcessMemory -SetLastError),\n    (func advapi32 RevertToSelf ([bool]) @(\n        # No Parameters\n    ) -EntryPoint RevertToSelf -SetLastError),\n    (func kernel32 Thread32First ([bool]) @(\n        [IntPtr],                                  #_In_    HANDLE          hSnapshot,\n        $THREADENTRY32.MakeByRefType()             #_Inout_ LPTHREADENTRY32 lpte\n    ) -EntryPoint Thread32First -SetLastError), \n    (func kernel32 Thread32Next ([bool]) @(\n        [IntPtr],                                  #_In_  HANDLE          hSnapshot,\n        $THREADENTRY32.MakeByRefType()             #_Out_ LPTHREADENTRY32 lpte\n    ) -EntryPoint Thread32Next -SetLastError),   \n    (func kernel32 VirtualQueryEx ([Int32]) @(\n        [IntPtr],                                  #_In_     HANDLE                    hProcess,\n        [IntPtr],                                  #_In_opt_ LPCVOID                   lpAddress,\n        $MEMORY_BASIC_INFORMATION.MakeByRefType(),   #_Out_    PMEMORY_BASIC_INFORMATION lpBuffer,\n        [UInt32]                                   #_In_     SIZE_T                    dwLength\n    ) -EntryPoint VirtualQueryEx -SetLastError)\n)\n\n$Types = $FunctionDefinitions | Add-Win32Type -Module $Module -Namespace ACE\n$advapi32 = $Types['advapi32']\n$iphlpapi = $Types['iphlpapi']\n$kernel32 = $Types['kernel32']\n$ntdll = $Types['ntdll']\n$secur32 = $Types['secur32']\n#endregion Function Definitions\n\n#region API Abstractions\nfunction CloseHandle\n{\n    <#\n    .SYNOPSIS\n\n    Closes an open object handle.\n\n    .DESCRIPTION\n\n    The CloseHandle function closes handles to the following objects:\n    - Access token\n    - Communications device\n    - Console input\n    - Console screen buffer\n    - Event\n    - File\n    - File mapping\n    - I/O completion port\n    - Job\n    - Mailslot\n    - Memory resource notification\n    - Mutex\n    - Named pipe\n    - Pipe\n    - Process\n    - Semaphore\n    - Thread\n    - Transaction\n    - Waitable timer\n    \n    The documentation for the functions that create these objects indicates that CloseHandle should be used when you are finished with the object, and what happens to pending operations on the object after the handle is closed. In general, CloseHandle invalidates the specified object handle, decrements the object's handle count, and performs object retention checks. After the last handle to an object is closed, the object is removed from the system. \n\n    .PARAMETER Handle\n\n    A valid handle to an open object.\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: PSReflect\n    Optional Dependencies: None\n    \n    (func kernel32 CloseHandle ([bool]) @(\n        [IntPtr] #_In_ HANDLE hObject\n    ) -EntryPoint CloseHandle -SetLastError)\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/ms724211(v=vs.85).aspx\n\n    .EXAMPLE\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $Handle    \n    )\n    \n    $SUCCESS = $Kernel32::CloseHandle($Handle); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n\n    if(-not $SUCCESS) \n    {\n        Write-Debug \"CloseHandle Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n}\n\nfunction ConvertSidToStringSid\n{\n    <#\n    .SYNOPSIS\n\n    The ConvertSidToStringSid function converts a security identifier (SID) to a string format suitable for display, storage, or transmission.\n\n    .DESCRIPTION\n\n    The ConvertSidToStringSid function uses the standard S-R-I-S-S… format for SID strings.\n    \n    .PARAMETER SidPointer\n\n    A pointer to the SID structure to be converted.\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: PSReflect\n    Optional Dependencies: None\n    \n    (func advapi32 ConvertSidToStringSid ([bool]) @(\n        [IntPtr]                 #_In_  PSID   Sid,\n        [IntPtr].MakeByRefType() #_Out_ LPTSTR *StringSid\n    ) -EntryPoint ConvertSidToStringSid -SetLastError)\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa376399(v=vs.85).aspx\n\n    .EXAMPLE\n    #>\n\n    [OutputType([string])]\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $SidPointer    \n    )\n    \n    $StringPtr = [IntPtr]::Zero\n    $Success = $Advapi32::ConvertSidToStringSid($SidPointer, [ref]$StringPtr); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n\n    if(-not $Success) \n    {\n        Write-Verbose \"ConvertSidToStringSid Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n    \n    Write-Output ([System.Runtime.InteropServices.Marshal]::PtrToStringAuto($StringPtr))\n}\n\nfunction CreateToolhelp32Snapshot\n{\n    <#\n    .SYNOPSIS\n\n    Takes a snapshot of the specified processes, as well as the heaps, modules, and threads used by these processes.\n\n    .DESCRIPTION\n\n    The snapshot taken by this function is examined by the other tool help functions to provide their results. Access to the snapshot is read only. The snapshot handle acts as an object handle and is subject to the same rules regarding which processes and threads it is valid in.\n\n    To enumerate the heap or module states for all processes, specify TH32CS_SNAPALL and set th32ProcessID to zero. Then, for each additional process in the snapshot, call CreateToolhelp32Snapshot again, specifying its process identifier and the TH32CS_SNAPHEAPLIST or TH32_SNAPMODULE value.\n\n    When taking snapshots that include heaps and modules for a process other than the current process, the CreateToolhelp32Snapshot function can fail or return incorrect information for a variety of reasons. For example, if the loader data table in the target process is corrupted or not initialized, or if the module list changes during the function call as a result of DLLs being loaded or unloaded, the function might fail with ERROR_BAD_LENGTH or other error code. Ensure that the target process was not started in a suspended state, and try calling the function again. If the function fails with ERROR_BAD_LENGTH when called with TH32CS_SNAPMODULE or TH32CS_SNAPMODULE32, call the function again until it succeeds.\n\n    The TH32CS_SNAPMODULE and TH32CS_SNAPMODULE32 flags do not retrieve handles for modules that were loaded with the LOAD_LIBRARY_AS_DATAFILE or similar flags. For more information, see LoadLibraryEx.\n\n    To destroy the snapshot, use the CloseHandle function.\n\n    Note that you can use the QueryFullProcessImageName function to retrieve the full name of an executable image for both 32- and 64-bit processes from a 32-bit process.\n\n    .PARAMETER ProcessId\n\n    The process identifier of the process to be included in the snapshot. This parameter can be zero to indicate the current process. This parameter is used when the TH32CS_SNAPHEAPLIST, TH32CS_SNAPMODULE, TH32CS_SNAPMODULE32, or TH32CS_SNAPALL value is specified. Otherwise, it is ignored and all processes are included in the snapshot.\n    \n    If the specified process is the Idle process or one of the CSRSS processes, this function fails and the last error code is ERROR_ACCESS_DENIED because their access restrictions prevent user-level code from opening them.\n    \n    If the specified process is a 64-bit process and the caller is a 32-bit process, this function fails and the last error code is ERROR_PARTIAL_COPY (299).\n\n    .PARAMETER Flags\n    \n    The portions of the system to be included in the snapshot.\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: PSReflect\n    Optional Dependencies: TH32CS (Enumeration)\n\n    (func kernel32 CreateToolhelp32Snapshot ([IntPtr]) @(\n        [UInt32], #_In_ DWORD dwFlags,\n        [UInt32]  #_In_ DWORD th32ProcessID\n    ) -EntryPoint CreateToolhelp32Snapshot -SetLastError)\n        \n    .LINK\n\n    .EXAMPLE\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [UInt32]\n        $ProcessId,\n        \n        [Parameter(Mandatory = $true)]\n        [UInt32]\n        $Flags\n    )\n    \n    $hSnapshot = $Kernel32::CreateToolhelp32Snapshot($Flags, $ProcessId); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n\n    if(-not $hSnapshot) \n    {\n        Write-Debug \"CreateToolhelp32Snapshot Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n    \n    Write-Output $hSnapshot\n}\n\nfunction DuplicateToken\n{\n    <#\n    .SYNOPSIS\n\n    The DuplicateToken function creates a new access token that duplicates one already in existence.\n\n    .DESCRIPTION\n\n    The DuplicateToken function creates an impersonation token, which you can use in functions such as SetThreadToken and ImpersonateLoggedOnUser. The token created by DuplicateToken cannot be used in the CreateProcessAsUser function, which requires a primary token. To create a token that you can pass to CreateProcessAsUser, use the DuplicateTokenEx function.\n\n    .PARAMETER TokenHandle\n\n    A handle to an access token opened with TOKEN_DUPLICATE access.\n\n    .PARAMETER ImpersonationLevel\n\n    Specifies a SECURITY_IMPERSONATION_LEVEL enumerated type that supplies the impersonation level of the new token. The Default is SecurityImpersonation.\n\n    .NOTES\n    \n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: PSReflect, SECURITY_IMPERSONATION_LEVEL (Enumeration)\n    Optional Dependencies: None\n\n    (func advapi32 DuplicateToken ([bool]) @(\n        [IntPtr]                 #_In_  HANDLE                       ExistingTokenHandle,\n        [UInt32]                 #_In_  SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,\n        [IntPtr].MakeByRefType() #_Out_ PHANDLE                      DuplicateTokenHandle\n    ) -EntryPoint DuplicateToken -SetLastError)\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa446616(v=vs.85).aspx\n\n    .EXAMPLE\n\n    #>\n\n    [OutputType([IntPtr])]\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $TokenHandle,\n\n        [Parameter()]\n        [ValidateSet('None','SecurityAnonymous','SecurityIdentification','SecurityImpersonation','SecurityDelegation')]\n        [string]\n        $ImpersonationLevel = 'SecurityImpersonation'\n    )\n\n    $DuplicateTokenHandle = [IntPtr]::Zero\n\n    $success = $Advapi32::DuplicateToken($TokenHandle, $SECURITY_IMPERSONATION_LEVEL::$ImpersonationLevel, [ref]$DuplicateTokenHandle); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n    \n    if(-not $success)\n    {\n        Write-Debug \"DuplicateToken Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n\n    Write-Output $DuplicateTokenHandle\n}\n\nfunction EnumerateSecurityPackages\n{\n    <#\n    .SYNOPSIS\n\n    The EnumerateSecurityPackages function returns an array of SecPkgInfo structures that provide information about the security packages available to the client.\n\n    .DESCRIPTION\n\n    The caller can use the Name member of a SecPkgInfo structure to specify a security package in a call to the AcquireCredentialsHandle (General) function.\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: FreeContextBuffer (function), SecPkgInfo (Structure), SECPKG_FLAG (Enumeration)\n    Optional Dependencies: None\n\n    (func secur32 EnumerateSecurityPackages ([UInt32]) @(\n        [UInt32].MakeByRefType(), #_In_ PULONG      pcPackages\n        [IntPtr].MakeByRefType()  #_In_ PSecPkgInfo *ppPackageInfo\n    ) -EntryPoint EnumerateSecurityPackages)\n\n    .LINK\n    \n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa375397(v=vs.85).aspx\n\n    .EXAMPLE\n\n    PS > EnumerateSecurityPackages\n\n    Name         : Negotiate\n    Comment      : Microsoft Package Negotiator\n    Capabilities : INTEGRITY, PRIVACY, CONNECTION, MULTI_REQUIRED, EXTENDED_ERROR, \n                   IMPERSONATION, ACCEPT_WIN32_NAME, NEGOTIABLE, GSS_COMPATIBLE, LOGON, \n                   RESTRICTED_TOKENS, APPCONTAINER_CHECKS\n    Version      : 1\n    RpcId        : 9\n    MaxToken     : 65791\n\n    Name         : NegoExtender\n    Comment      : NegoExtender Security Package\n    Capabilities : INTEGRITY, PRIVACY, CONNECTION, IMPERSONATION, NEGOTIABLE, GSS_COMPATIBLE, \n                   LOGON, MUTUAL_AUTH, NEGO_EXTENDER, APPCONTAINER_CHECKS\n    Version      : 1\n    RpcId        : 30\n    MaxToken     : 12000\n\n    Name         : Kerberos\n    Comment      : Microsoft Kerberos V1.0\n    Capabilities : INTEGRITY, PRIVACY, TOKEN_ONLY, DATAGRAM, CONNECTION, MULTI_REQUIRED, \n                   EXTENDED_ERROR, IMPERSONATION, ACCEPT_WIN32_NAME, NEGOTIABLE, \n                   GSS_COMPATIBLE, LOGON, MUTUAL_AUTH, DELEGATION, READONLY_WITH_CHECKSUM, \n                   RESTRICTED_TOKENS, APPCONTAINER_CHECKS\n    Version      : 1\n    RpcId        : 16\n    MaxToken     : 65535\n\n    Name         : NTLM\n    Comment      : NTLM Security Package\n    Capabilities : INTEGRITY, PRIVACY, TOKEN_ONLY, CONNECTION, MULTI_REQUIRED, IMPERSONATION, \n                   ACCEPT_WIN32_NAME, NEGOTIABLE, LOGON, RESTRICTED_TOKENS, APPCONTAINER_CHECKS\n    Version      : 1\n    RpcId        : 10\n    MaxToken     : 2888\n\n    Name         : TSSSP\n    Comment      : TS Service Security Package\n    Capabilities : CONNECTION, MULTI_REQUIRED, ACCEPT_WIN32_NAME, MUTUAL_AUTH, \n                   APPCONTAINER_CHECKS\n    Version      : 1\n    RpcId        : 22\n    MaxToken     : 13000\n\n    Name         : pku2u\n    Comment      : PKU2U Security Package\n    Capabilities : INTEGRITY, PRIVACY, CONNECTION, IMPERSONATION, GSS_COMPATIBLE, MUTUAL_AUTH, \n                   NEGOTIABLE2, APPCONTAINER_CHECKS\n    Version      : 1\n    RpcId        : 31\n    MaxToken     : 12000\n\n    Name         : CloudAP\n    Comment      : Cloud AP Security Package\n    Capabilities : LOGON, NEGOTIABLE2\n    Version      : 1\n    RpcId        : 36\n    MaxToken     : 0\n\n    Name         : WDigest\n    Comment      : Digest Authentication for Windows\n    Capabilities : TOKEN_ONLY, IMPERSONATION, ACCEPT_WIN32_NAME, APPCONTAINER_CHECKS\n    Version      : 1\n    RpcId        : 21\n    MaxToken     : 4096\n\n    Name         : Schannel\n    Comment      : Schannel Security Package\n    Capabilities : INTEGRITY, PRIVACY, CONNECTION, MULTI_REQUIRED, EXTENDED_ERROR, \n                   IMPERSONATION, ACCEPT_WIN32_NAME, STREAM, MUTUAL_AUTH, \n                   APPCONTAINER_PASSTHROUGH\n    Version      : 1\n    RpcId        : 14\n    MaxToken     : 24576\n\n    Name         : Microsoft Unified Security Protocol Provider\n    Comment      : Schannel Security Package\n    Capabilities : INTEGRITY, PRIVACY, CONNECTION, MULTI_REQUIRED, EXTENDED_ERROR, \n                   IMPERSONATION, ACCEPT_WIN32_NAME, STREAM, MUTUAL_AUTH, \n                   APPCONTAINER_PASSTHROUGH\n    Version      : 1\n    RpcId        : 14\n    MaxToken     : 24576\n\n    Name         : CREDSSP\n    Comment      : Microsoft CredSSP Security Provider\n    Capabilities : INTEGRITY, PRIVACY, CONNECTION, MULTI_REQUIRED, IMPERSONATION, \n                   ACCEPT_WIN32_NAME, STREAM, MUTUAL_AUTH, APPCONTAINER_CHECKS\n    Version      : 1\n    RpcId        : 65535\n    MaxToken     : 90567\n    #>\n\n    $PackageCount = 0\n    $PackageInfo = [IntPtr]::Zero\n\n    $SUCCESS = $Secur32::EnumerateSecurityPackages([ref]$PackageCount, [ref]$PackageInfo)\n\n    if($SUCCESS -ne 0)\n    {\n        throw \"EnumerateSecurityPackages Error: $($SUCCESS)\"\n    }\n\n    for($i = 0; $i -lt $PackageCount; $i++)\n    {\n        $PackagePtr = [IntPtr]($PackageInfo.ToInt64() + ($SecPkgInfo::GetSize() * $i))\n\n        $Package = $PackagePtr -as $SecPkgInfo\n        \n        $obj = New-Object -TypeName psobject\n        $obj | Add-Member -MemberType NoteProperty -Name Name -Value ([System.Runtime.InteropServices.Marshal]::PtrToStringAuto($Package.Name))\n        $obj | Add-Member -MemberType NoteProperty -Name Comment -Value ([System.Runtime.InteropServices.Marshal]::PtrToStringAuto($Package.Comment))\n        $obj | Add-Member -MemberType NoteProperty -Name Capabilities -Value $Package.Capabilities\n        $obj | Add-Member -MemberType NoteProperty -Name Version -Value $Package.Version\n        $obj | Add-Member -MemberType NoteProperty -Name RpcId -Value $Package.RPCID\n        $obj | Add-Member -MemberType NoteProperty -Name MaxToken -Value $Package.MaxToken\n\n        Write-Output $obj\n    }\n\n    FreeContextBuffer -Buffer $PackageInfo\n}\n\nfunction FreeContextBuffer\n{\n    <#\n    .SYNOPSIS\n\n    The FreeContextBuffer function enables callers of security package functions to free memory buffers allocated by the security package.\n\n    .DESCRIPTION\n\n    Memory buffers are typically allocated by the InitializeSecurityContext (General) and AcceptSecurityContext (General) functions.\n    \n    The FreeContextBuffer function can free any memory allocated by a security package.\n\n    .PARAMETER Buffer\n\n    A pointer to memory to be freed.\n\n    .NOTES\n    \n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: None\n    Optional Dependencies: None\n\n    (func secur32 FreeContextBuffer ([UInt32]) @(\n          [IntPtr] #_In_ PVOID pvContextBuffer\n    ) -EntryPoint FreeContextBuffer)\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa375416(v=vs.85).aspx\n\n    .EXAMPLE\n\n    PS > $PackageCount = 0\n    PS > $PackageInfo = [IntPtr]::Zero\n\n    PS > $SUCCESS = $Secur32::EnumerateSecurityPackages([ref]$PackageCount, [ref]$PackageInfo)\n\n    #\n    # Do Stuff ...\n    #\n\n    PS > FreeContextBuffer -Buffer $PackageInfo\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $Buffer\n    )\n\n    $SUCCESS = $Secur32::FreeContextBuffer($Buffer)\n\n    if($SUCCESS -ne 0)\n    {\n        throw \"FreeContextBuffer Error: $($SUCCESS)\"\n    }\n}\n\nfunction GetIpNetTable\n{\n    <#\n    .SYNOPSIS\n\n    Retreives the IPv4 to physical address mapping table.\n\n    .DESCRIPTION\n\n    The GetIpNetTable function enumerates the Address Resolution Protocol (ARP) entries for IPv4 on a local system from the IPv4 to physical address mapping table and returns this information in a MIB_IPNETTABLE structure.\n\n    on Windows Vista and later, the GetIpNetTable2 function can be used to retrieve the neighbor IP addresses for both IPv6 and IPv4.\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: MIB_IPNETROW (Struct), MIB_IPNET_TYPE (Enum)\n    Optional Dependencies: None\n    \n    (func iphlpapi GetIpNetTable ([Int32]) @(\n        [IntPtr],                 #_Out_   PMIB_IPNETTABLE pIpNetTable\n        [Int32].MakeByRefType(),  #_Inout_ PULONG          pdwSize\n        [bool]                    #_In_    BOOL            bOrder\n    ))\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa365956%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396\n\n    .EXAMPLE\n\n    GetIpNetTable\n\n    AdapterIndex PhysicalAddress   IpAddress          Type\n    ------------ ---------------   ---------          ----\n              14 00-50-56-C0-00-08 192.168.1.1      DYNAMIC\n              14 00-50-56-F8-64-30 192.168.1.2      DYNAMIC\n              14 00-0C-29-BB-51-6D 192.168.1.137    DYNAMIC\n              14 00-00-00-00-00-00 192.168.1.254    INVALID\n              14 FF-FF-FF-FF-FF-FF 192.168.1.255    STATIC\n              14 01-00-5E-00-00-16 224.0.0.22       STATIC\n              14 01-00-5E-00-00-FC 224.0.0.252      STATIC\n              14 01-00-5E-7F-FF-FA 239.255.255.250  STATIC\n              14 FF-FF-FF-FF-FF-FF 255.255.255.255  STATIC\n               1 00-00-00-00-00-00 224.0.0.22       STATIC\n               1 00-00-00-00-00-00 224.0.0.252      STATIC\n               1 00-00-00-00-00-00 239.255.255.250  STATIC\n              11 01-00-5E-00-00-16 224.0.0.22       STATIC\n              10 01-00-5E-00-00-16 224.0.0.22       STATIC\n    #>\n\n    $pThrowAway = [IntPtr]::Zero\n    $dwSize = [Int32]0\n\n    # Run the function once to get the size of the MIB_NETTABLE Structure\n    $SUCCESS = $iphlpapi::GetIpNetTable($pThrowAway, [ref]$dwSize, $false)\n    \n    # ERROR_INSUFFICIENT_BUFFER means that $dwSize now contains the size of the stucture\n    if($SUCCESS -eq 122)\n    {\n        $pIpNetTable = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($dwSize)\n        $SUCCESS = $iphlpapi::GetIpNetTable($pIpNetTable, [ref]$dwSize, $false)\n        \n        if($SUCCESS -eq 0)\n        {\n            $count = [System.Runtime.InteropServices.Marshal]::ReadInt32($pIpNetTable)\n\n            for($i = 0; $i -lt $count; $i++)\n            {\n                $CurrentPtr = [IntPtr]($pIpNetTable.ToInt64() + 4 + ($i * 24))\n                $IpNetRow = $CurrentPtr -as $MIB_IPNETROW\n    \n                [byte[]]$bAddress = $IpNetRow.bPhysAddr\n\n                $obj = @{\n                    AdapterIndex = $IpNetRow.dwIndex\n                    PhysicalAddress = [System.BitConverter]::ToString($bAddress).Replace('-',':')\n                    IpAddress = [string]((New-Object -TypeName System.Net.IPAddress($IpNetRow.dwAddr)).IPAddressToString)\n                    Type = [string]($IpNetRow.dwType -as $MIB_IPNET_TYPE)\n                }\n\n                Write-Output $obj\n            }\n        }\n    }\n\n    [System.Runtime.InteropServices.Marshal]::FreeHGlobal($pIpNetTable)\n}\n\nfunction GetTokenInformation\n{\n    <#\n    .SYNOPSIS\n\n    The GetTokenInformation function retrieves a specified type of information about an access token. The calling process must have appropriate access rights to obtain the information.\n    \n    To determine if a user is a member of a specific group, use the CheckTokenMembership function. To determine group membership for app container tokens, use the CheckTokenMembershipEx function.\n\n    .PARAMETER TokenHandle\n\n    A handle to an access token from which information is retrieved. If TokenInformationClass specifies TokenSource, the handle must have TOKEN_QUERY_SOURCE access. For all other TokenInformationClass values, the handle must have TOKEN_QUERY access.\n\n    .PARAMETER TokenInformationClass\n\n    Specifies a value from the TOKEN_INFORMATION_CLASS enumerated type to identify the type of information the function retrieves. Any callers who check the TokenIsAppContainer and have it return 0 should also verify that the caller token is not an identify level impersonation token. If the current token is not an app container but is an identity level token, you should return AccessDenied.\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Module Dependencies: PSReflect\n    Required Function Dependencies: ConvertSidToStringSid\n    Required Structure Dependencies: TOKEN_USER, SID_AND_ATTRIBUTES, TOKEN_PRIVILEGES, TOKEN_OWNER, TOKEN_SOURCE, LUID, TOKEN_MANDATORY_LABEL\n    Required Enumeration Dependencies: LuidAttributes, TOKEN_TYPE, SECURITY_IMPERSONATION_LEVEL\n    Optional Dependencies: TokenInformationClass (Enum)\n\n    (func advapi32 GetTokenInformation ([bool]) @(\n        [IntPtr],                #_In_      HANDLE                  TokenHandle\n        [Int32],                 #_In_      TOKEN_INFORMATION_CLASS TokenInformationClass\n        [IntPtr],                #_Out_opt_ LPVOID                  TokenInformation\n        [UInt32],                #_In_      DWORD                   TokenInformationLength\n        [UInt32].MakeByRefType() #_Out_     PDWORD                  ReturnLength\n    ) -EntryPoint GetTokenInformation -SetLastError)\n        \n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa446671(v=vs.85).aspx\n\n    .EXAMPLE\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $TokenHandle,\n        \n        [Parameter(Mandatory = $true)]\n        [ValidateSet('TokenUser','TokenGroups','TokenPrivileges','TokenOwner','TokenPrimaryGroup','TokenDefaultDacl','TokenSource','TokenType','TokenImpersonationLevel','TokenStatistics','TokenRestrictedSids','TokenSessionId','TokenGroupsAndPrivileges','TokenSandBoxInert','TokenOrigin','TokenElevationType','TokenLinkedToken','TokenElevation','TokenHasRestrictions','TokenAccessInformation','TokenVirtualizationAllowed','TokenVirtualizationEnabled','TokenIntegrityLevel','TokenUIAccess','TokenMandatoryPolicy','TokenLogonSid','TokenIsAppContainer','TokenCapabilities','TokenAppContainerSid','TokenAppContainerNumber','TokenUserClaimAttributes','TokenDeviceClaimAttributes','TokenDeviceGroups','TokenRestrictedDeviceGroups')]\n        [string]\n        $TokenInformationClass\n    )\n\n    # initial query to determine the necessary buffer size\n    $TokenPtrSize = 0\n    $SUCCESS = $Advapi32::GetTokenInformation($TokenHandle, $TOKEN_INFORMATION_CLASS::$TokenInformationClass, [IntPtr]::Zero, $TokenPtrSize, [ref]$TokenPtrSize); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n\n    [IntPtr]$TokenPtr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($TokenPtrSize)\n\n    # retrieve the proper buffer value\n    $SUCCESS = $Advapi32::GetTokenInformation($TokenHandle, $TOKEN_INFORMATION_CLASS::$TokenInformationClass, $TokenPtr, $TokenPtrSize, [ref]$TokenPtrSize); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n    \n    if(-not $SUCCESS)\n    {\n        [System.Runtime.InteropServices.Marshal]::FreeHGlobal($TokenPtr)\n        throw \"GetTokenInformation Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n\n    switch($TokenInformationClass)\n    {\n        TokenUser\n        {\n            <#\n            The buffer receives a TOKEN_USER structure that contains the user account of the token.\n                ConvertSidToStringSid (Function)\n                TOKEN_USER (Structure)\n                SID_AND_ATTRIBUTES (Structure)\n            #>\n            $TokenUser = $TokenPtr -as $TOKEN_USER\n            $UserSid = ConvertSidToStringSid -SidPointer $TokenUser.User.Sid\n\n            $Sid = New-Object System.Security.Principal.SecurityIdentifier($UserSid)\n            $UserName = $Sid.Translate([System.Security.Principal.NTAccount])\n\n            $obj = New-Object -TypeName psobject\n\n            $obj | Add-Member -MemberType NoteProperty -Name Sid -Value $UserSid\n            $obj | Add-Member -MemberType NoteProperty -Name Name -Value $UserName\n\n            Write-Output $obj\n        }\n        TokenGroups\n        {\n            <#\n            The buffer receives a TOKEN_GROUPS structure that contains the group accounts associated with the token.\n                TOKEN_GROUPS (Structure)\n                SID_AND_ATTRIBUTES (Structure)\n            #>\n            $TokenGroups = ($TokenPtr -as $TOKEN_GROUPS)\n\n            for($i = 0; $i -lt $TokenGroups.GroupCount; $i++)\n            {\n                $obj = New-Object -TypeName psobject\n\n                $obj | Add-Member -MemberType NoteProperty -Name Sid -Value (ConvertSidToStringSid -SidPointer $TokenGroups.Groups[$i].Sid)\n                $obj | Add-Member -MemberType NoteProperty -Name Attributes -Value $TokenGroups.Groups[$i].Attributes\n\n                Write-Output $obj\n            }\n        }\n        TokenPrivileges\n        {\n            <#\n            The buffer receives a TOKEN_PRIVILEGES structure that contains the privileges of the token.\n                TOKEN_PRIVILEGES (Structure)\n                LUID_AND_ATTRIBUTES (Structure)\n                LuidAttributes (Enumeration)\n            #>\n            $TokenPrivileges = $TokenPtr -as $TOKEN_PRIVILEGES\n                \n            for($i = 0; $i -lt $TokenPrivileges.PrivilegeCount; $i++)\n            {\n                $obj = New-Object -TypeName psobject\n                \n                $obj | Add-Member -MemberType NoteProperty -Name Privilege -Value (LookupPrivilegeName -PrivilegeValue $TokenPrivileges.Privileges[$i].Luid.LowPart)\n                $obj | Add-Member -MemberType NoteProperty -Name Attributes -Value $TokenPrivileges.Privileges[$i].Attributes\n                    \n                Write-Output $obj   \n            }\n\n        }\n        TokenOwner\n        {\n            <#\n            The buffer receives a TOKEN_OWNER structure that contains the default owner security identifier (SID) for newly created objects.\n                ConvertSidToStringSid (Function)\n                TOKEN_OWNER (Structure)\n            #>\n            $TokenOwner = $TokenPtr -as $TOKEN_OWNER\n    \n            if($TokenOwner.Owner -ne $null)\n            {\n                $OwnerSid = ConvertSidToStringSid -SidPointer $TokenOwner.Owner\n                \n                $Sid = New-Object System.Security.Principal.SecurityIdentifier($OwnerSid)\n                $OwnerName = $Sid.Translate([System.Security.Principal.NTAccount])\n\n                $obj = New-Object -TypeName psobject\n\n                $obj | Add-Member -MemberType NoteProperty -Name Sid -Value $OwnerSid\n                $obj | Add-Member -MemberType NoteProperty -Name Name -Value $OwnerName\n\n                Write-Output $obj\n            }\n            else\n            {\n                Write-Output $null\n            }\n        }\n        TokenPrimaryGroup\n        {\n            <#\n            The buffer receives a TOKEN_PRIMARY_GROUP structure that contains the default primary group SID for newly created objects.\n                TOKEN_PRIMARY_GROUP (Structure)\n            #>\n            throw [System.NotImplementedException]\"The $($TokenInformationClass) class is not implemented yet.\"\n        }\n        TokenDefaultDacl\n        {\n            <#\n            The buffer receives a TOKEN_DEFAULT_DACL structure that contains the default DACL for newly created objects.\n                TOKEN_DEFAULT_DACL (Structure)\n                ACL (Structure)\n            #>\n            $Dacl = $TokenPtr -as $TOKEN_DEFAULT_DACL\n            Write-Output $Dacl.DefaultDacl\n        }\n        TokenSource\n        {\n            <#\n            The buffer receives a TOKEN_SOURCE structure that contains the source of the token. TOKEN_QUERY_SOURCE access is needed to retrieve this information.\n                TOKEN_SOURCE (Structure)\n                LUID (Structure)\n            #>\n            \n            Write-Output $TokenPtr\n            #$TokenSource = $TokenPtr -as $TOKEN_SOURCE\n            #Write-Output ($TokenSource.SourceName -join \"\")\n        }\n        TokenType\n        {\n            <#\n            The buffer receives a TOKEN_TYPE value that indicates whether the token is a primary or impersonation token.\n                TOKEN_TYPE (Enumeration)\n            #>\n            if($TokenPtr -ne $null)\n            {\n                Write-Output ([System.Runtime.InteropServices.Marshal]::ReadInt32($TokenPtr) -as $TOKEN_TYPE)\n            }\n        }\n        TokenImpersonationLevel\n        {\n            <#\n            The buffer receives a SECURITY_IMPERSONATION_LEVEL value that indicates the impersonation level of the token. If the access token is not an impersonation token, the function fails.\n                SECURITY_IMPERSONATION_LEVEL (Enumeration)\n            #>\n            Write-Output ([System.Runtime.InteropServices.Marshal]::ReadInt32($TokenPtr) -as $SECURITY_IMPERSONATION_LEVEL)\n        }\n        TokenStatistics\n        {\n            <#\n            The buffer receives a TOKEN_STATISTICS structure that contains various token statistics.\n                TOKEN_STATISTICS (Structure)\n                LUID (Structure)\n                TOKEN_TYPE (Enumeration)\n                SECURITY_IMPERSONATION_LEVEL (Enumeration)\n            #>\n            $TokenStats = $TokenPtr -as $TOKEN_STATISTICS\n\n            $obj = New-Object -TypeName psobject\n\n            $obj | Add-Member -MemberType NoteProperty -Name TokenId -Value $TokenStats.TokenId.LowPart\n            $obj | Add-Member -MemberType NoteProperty -Name AuthenticationId -Value $TokenStats.AuthenticationId.LowPart\n            $obj | Add-Member -MemberType NoteProperty -Name TokenType -Value $TokenStats.TokenType\n            $obj | Add-Member -MemberType NoteProperty -Name ImpersonationLevel -Value $TokenStats.ImpersonationLevel\n            $obj | Add-Member -MemberType NoteProperty -Name DynamicCharged -Value $TokenStats.DynamicCharged\n            $obj | Add-Member -MemberType NoteProperty -Name DynamicAvailable -Value $TokenStats.DynamicAvailable\n            $obj | Add-Member -MemberType NoteProperty -Name GroupCount -Value $TokenStats.GroupCount\n            $obj | Add-Member -MemberType NoteProperty -Name PrivilegeCount -Value $TokenStats.PrivilegeCount\n            $obj | Add-Member -MemberType NoteProperty -Name ModifiedId -Value $TokenStats.ModifiedId.LowPart\n                \n            Write-Output $obj\n        }\n        TokenRestrictedSids\n        {\n            <#\n            The buffer receives a TOKEN_GROUPS structure that contains the list of restricting SIDs in a restricted token.\n                TOKEN_GROUPS (Structure)\n                SID_AND_ATTRIBUTES (Structure)\n            #>\n            $TokenGroups = ($TokenPtr -as $TOKEN_GROUPS)\n\n            for($i = 0; $i -lt $TokenGroups.GroupCount; $i++)\n            {\n                $obj = New-Object -TypeName psobject\n\n                $obj | Add-Member -MemberType NoteProperty -Name Sid -Value (ConvertSidToStringSid -SidPointer $TokenGroups.Groups[$i].Sid)\n                $obj | Add-Member -MemberType NoteProperty -Name Attributes -Value $TokenGroups.Groups[$i].Attributes\n\n                Write-Output $obj\n            }\n        }\n        TokenSessionId\n        {\n            # The buffer receives a DWORD value that indicates the Terminal Services session identifier that is associated with the token.\n            # If the token is associated with the terminal server client session, the session identifier is nonzero.\n            # Windows Server 2003 and Windows XP:  If the token is associated with the terminal server console session, the session identifier is zero.\n            # In a non-Terminal Services environment, the session identifier is zero.\n            # If TokenSessionId is set with SetTokenInformation, the application must have the Act As Part Of the Operating System privilege, and the application must be enabled to set the session ID in a token.\n            Write-Output ([System.Runtime.InteropServices.Marshal]::ReadInt32($TokenPtr))\n        }\n        TokenGroupsAndPrivileges\n        {\n            <#\n            The buffer receives a TOKEN_GROUPS_AND_PRIVILEGES structure that contains the user SID, the group accounts, the restricted SIDs, and the authentication ID associated with the token.\n                TOKEN_GROUPS_AND_PRIVILEGES (Structure)\n                SID_AND_ATTRIBUTES (Structure)\n                LUID (Structure)\n            #>\n            $GroupsAndPrivs = ($TokenPtr -as $TOKEN_GROUPS_AND_PRIVILEGES)\n                \n            $SidList = New-Object -TypeName 'System.Collections.Generic.List[System.Object]'\n\n            for($i = 0; $i -lt $GroupsAndPrivs.SidCount; $i++)\n            {\n                $currentPtr = [IntPtr]($GroupsAndPrivs.Sids.ToInt64() + ($SID_AND_ATTRIBUTES::GetSize() * $i))\n                $SidAndAttr = $currentPtr -as $SID_AND_ATTRIBUTES\n\n                $obj = New-Object -TypeName psobject\n\n                $obj | Add-Member -MemberType NoteProperty -Name Sid -Value (ConvertSidToStringSid -SidPointer $SidAndAttr.Sid)\n                $obj | Add-Member -MemberType NoteProperty -Name Attributes -Value $SidAndAttr.Attributes\n\n                $SidList.Add($obj)\n            }\n                \n            $PrivList = New-Object -TypeName 'System.Collections.Generic.List[System.Object]'\n\n            for($i = 0; $i -lt $GroupsAndPrivs.PrivilegeCount; $i++)\n            {\n                $currentPtr = [IntPtr]($GroupsAndPrivs.Privileges.ToInt64() + ($LUID_AND_ATTRIBUTES::GetSize() * $i))\n                $LuidAndAttr = ($currentPtr -as $LUID_AND_ATTRIBUTES)\n\n                $obj = New-Object -TypeName psobject\n\n                $obj | Add-Member -MemberType NoteProperty -Name Privilege -Value $LuidAndAttr.Luid.LowPart\n                $obj | Add-Member -MemberType NoteProperty -Name Attributes -Value $LuidAndAttr.Attributes\n\n                $PrivList.Add($obj)\n            }\n\n            $obj = New-Object -TypeName psobject\n\n            $obj | Add-Member -MemberType NoteProperty -Name Sids -Value $SidList.ToArray()\n            $obj | Add-Member -MemberType NoteProperty -Name Privilegs -Value $PrivList.ToArray()\n\n            Write-Output $obj\n        }\n        TokenSandBoxInert\n        {\n            # The buffer receives a DWORD value that is nonzero if the token includes the SANDBOX_INERT flag.\n            Write-Output (0 -ne ([System.Runtime.InteropServices.Marshal]::ReadInt32($TokenPtr)))\n        }\n        TokenOrigin\n        {\n            <#\n            The buffer receives a TOKEN_ORIGIN value.\n            If the token resulted from a logon that used explicit credentials, such as passing a name, domain, and password to the LogonUser function, then the TOKEN_ORIGIN structure will contain the ID of the logon session that created it.\n            If the token resulted from network authentication, such as a call to AcceptSecurityContext or a call to LogonUser with dwLogonType set to LOGON32_LOGON_NETWORK or LOGON32_LOGON_NETWORK_CLEARTEXT, then this value will be zero.\n                TOKEN_ORIGIN (Structure)\n                LUID (Structure)\n            #>\n            $TokenOrigin = $TokenPtr -as $LUID\n            Write-Output $TokenOrigin.LowPart\n        }\n        TokenElevationType\n        {\n            <#\n            The buffer receives a TOKEN_ELEVATION_TYPE value that specifies the elevation level of the token.\n                TOKEN_ELEVATION_TYPE (Enumeration)\n            #>\n            Write-Output ([System.Runtime.InteropServices.Marshal]::ReadInt32($TokenPtr) -as $TOKEN_ELEVATION_TYPE)\n        }\n        TokenLinkedToken\n        {\n            <#\n            The buffer receives a TOKEN_LINKED_TOKEN structure that contains a handle to another token that is linked to this token.\n                TOKEN_LINKED_TOKEN (Structure)\n            #>\n            Write-Output ($TokenPtr -as $TOKEN_LINKED_TOKEN).LinkedToken\n        }\n        TokenElevation\n        {\n            <#\n            The buffer receives a TOKEN_ELEVATION structure that specifies whether the token is elevated.                                    \n                TOKEN_ELEVATION (Structure)\n            #>\n            Write-Output (($TokenPtr -as $TOKEN_ELEVATION).TokenIsElevated -ne 0)\n        }\n        TokenHasRestrictions\n        {\n            # The buffer receives a DWORD value that is nonzero if the token has ever been filtered.\n            Write-Output (0 -ne ([System.Runtime.InteropServices.Marshal]::ReadInt32($TokenPtr)))\n        }\n        TokenAccessInformation\n        {\n            <#\n            The buffer receives a TOKEN_ACCESS_INFORMATION structure that specifies security information contained in the token.\n                TOKEN_ACCESS_INFORMATION (Structure)\n                SID_AND_ATTRIBUTES_HASH (Structure)\n                SID_HASH_ENTRY (Structure)\n                TOKEN_PRIVILEGES (Structure)\n                LUID_AND_ATTRIBUTES (Structure)\n                LUID (Structure)\n                TOKEN_TYPE (Enumeration)\n                SECURITY_IMPERSONATION_LEVEL (Enumeration)\n                TOKEN_MANDATORY_POLICY (Structure)\n            #>\n            <#\n            $TokenAccessInfo = ($TokenPtr -as $TOKEN_ACCESS_INFORMATION)\n                \n            $obj = New-Object -TypeName psobject\n\n            $obj | Add-Member -MemberType NoteProperty -Name SidHash -Value ($TokenAccessInfo.SidHash -as $SID_AND_ATTRIBUTES_HASH)\n            $obj | Add-Member -MemberType NoteProperty -Name RestrictedSidHash -Value ($TokenAccessInfo.RestrictedSidHash -as $SID_AND_ATTRIBUTES_HASH)\n            $obj | Add-Member -MemberType NoteProperty -Name Privileges -Value ($TokenAccessInfo.Privileges -as $TOKEN_PRIVILEGES)\n            $obj | Add-Member -MemberType NoteProperty -Name AuthenticationId -Value $TokenAccessInfo.AuthenticationId.LowPart\n            $obj | Add-Member -MemberType NoteProperty -Name TokenType -Value $TokenAccessInfo.TokenType\n            $obj | Add-Member -MemberType NoteProperty -Name ImpersonationLevel -Value $TokenAccessInfo.ImpersonationLevel\n            $obj | Add-Member -MemberType NoteProperty -Name AppContainerNumber -Value $TokenAccessInfo.AppContainerNumber\n            $obj | Add-Member -MemberType NoteProperty -Name PackageSid -Value (ConvertSidToStringSid -SidPointer $TokenAccessInfo.PackageSid)\n            $obj | Add-Member -MemberType NoteProperty -Name CapabilitiesHash -Value ($TokenAccessInfo.CapabilitiesHash -as $SID_AND_ATTRIBUTES_HASH)\n            $obj | Add-Member -MemberType NoteProperty -Name TrustLevelSid -Value (ConvertSidToStringSid -SidPointer $TokenAccessInfo.TrustLevelSid)\n\n            Write-Output $obj\n            #>\n\n            Write-Output $TokenPtr\n            #throw [System.NotImplementedException]\"The $($TokenInformationClass) class is not implemented yet.\"\n        }\n        TokenVirtualizationAllowed\n        {\n            # The buffer receives a DWORD value that is nonzero if virtualization is allowed for the token.\n            Write-Output (0 -ne ([System.Runtime.InteropServices.Marshal]::ReadInt32($TokenPtr)))\n        }\n        TokenVirtualizationEnabled\n        {\n            # The buffer receives a DWORD value that is nonzero if virtualization is enabled for the token.\n            Write-Output (0 -ne ([System.Runtime.InteropServices.Marshal]::ReadInt32($TokenPtr)))\n        }\n        TokenIntegrityLevel\n        {\n            <#\n            The buffer receives a TOKEN_MANDATORY_LABEL structure that specifies the token's integrity level.\n                TOKEN_MANDATORY_LABEL\n                ConvertSidToStringSid\n            #>\n            $TokenIntegrity = $TokenPtr -as $TOKEN_MANDATORY_LABEL\n\n            switch(ConvertSidToStringSid -SidPointer $TokenIntegrity.Label.Sid)\n            {\n                S-1-16-0\n                {\n                    Write-Output \"UNTRUSTED_MANDATORY_LEVEL\"\n                }\n                S-1-16-4096\n                {\n                    Write-Output \"LOW_MANDATORY_LEVEL\"\n                }\n                S-1-16-8192\n                {\n                    Write-Output \"MEDIUM_MANDATORY_LEVEL\"\n                }\n                S-1-16-8448\n                {\n                    Write-Output \"MEDIUM_PLUS_MANDATORY_LEVEL\"\n                }\n                S-1-16-12288\n                {\n                    Write-Output \"HIGH_MANDATORY_LEVEL\"\n                }\n                S-1-16-16384\n                {\n                    Write-Output \"SYSTEM_MANDATORY_LEVEL\"\n                }\n                S-1-16-20480\n                {\n                    Write-Output \"PROTECTED_PROCESS_MANDATORY_LEVEL\"\n                }\n                S-1-16-28672\n                {\n                    Write-Output \"SECURE_PROCESS_MANDATORY_LEVEL\"\n                }\n            }\n        }\n        TokenUIAccess\n        {\n            # The buffer receives a DWORD value that is nonzero if the token has the UIAccess flag set.\n            Write-Output (0 -ne ([System.Runtime.InteropServices.Marshal]::ReadInt32($TokenPtr)))\n        }\n        TokenMandatoryPolicy\n        {\n            <#\n            The buffer receives a TOKEN_MANDATORY_POLICY structure that specifies the token's mandatory integrity policy.\n                TOKEN_MANDATORY_POLICY\n                TOKENMANDATORYPOLICY\n            #>\n            $MandatoryPolicy = $TokenPtr -as $TOKEN_MANDATORY_POLICY\n            Write-Output $MandatoryPolicy.Policy\n        }\n        TokenLogonSid\n        {\n            <#\n            The buffer receives a TOKEN_GROUPS structure that specifies the token's logon SID.\n                TOKEN_GROUPS (Structure)\n                SID_AND_ATTRIBUTES (Structure)\n            #>\n            $TokenGroups = ($TokenPtr -as $TOKEN_GROUPS)\n\n            for($i = 0; $i -lt $TokenGroups.GroupCount; $i++)\n            {\n                $obj = New-Object -TypeName psobject\n\n                $obj | Add-Member -MemberType NoteProperty -Name Sid -Value (ConvertSidToStringSid -SidPointer $TokenGroups.Groups[$i].Sid)\n                $obj | Add-Member -MemberType NoteProperty -Name Attributes -Value $TokenGroups.Groups[$i].Attributes\n\n                Write-Output $obj\n            }\n        }\n        TokenIsAppContainer\n        {\n            # The buffer receives a DWORD value that is nonzero if the token is an app container token. Any callers who check the TokenIsAppContainer and have it return 0 should also verify that the caller token is not an identify level impersonation token. If the current token is not an app container but is an identity level token, you should return AccessDenied.\n            Write-Output (0 -ne ([System.Runtime.InteropServices.Marshal]::ReadInt32($TokenPtr)))\n        }\n        TokenCapabilities\n        {\n            <#\n            The buffer receives a TOKEN_GROUPS structure that contains the capabilities associated with the token.\n                TOKEN_GROUPS (Structure)\n                SID_AND_ATTRIBUTES (Structure)\n            #>\n            $TokenGroups = ($TokenPtr -as $TOKEN_GROUPS)\n\n            for($i = 0; $i -lt $TokenGroups.GroupCount; $i++)\n            {\n                $obj = New-Object -TypeName psobject\n\n                $obj | Add-Member -MemberType NoteProperty -Name Sid -Value (ConvertSidToStringSid -SidPointer $TokenGroups.Groups[$i].Sid)\n                $obj | Add-Member -MemberType NoteProperty -Name Attributes -Value $TokenGroups.Groups[$i].Attributes\n\n                Write-Output $obj\n            }\n        }\n        TokenAppContainerSid\n        {\n            <#\n            The buffer receives a TOKEN_APPCONTAINER_INFORMATION structure that contains the AppContainerSid associated with the token. If the token is not associated with an app container, the TokenAppContainer member of the TOKEN_APPCONTAINER_INFORMATION structure points to NULL.\n                TOKEN_APPCONTAINER_INFORMATION (Structure)\n            #>\n            Write-Output ($TokenPtr -as $TOKEN_APPCONTAINER_INFORMATION)\n        }\n        TokenAppContainerNumber\n        {\n            # The buffer receives a DWORD value that includes the app container number for the token. For tokens that are not app container tokens, this value is zero.\n            Write-Output ([System.Runtime.InteropServices.Marshal]::ReadInt32($TokenPtr))\n        }\n        TokenUserClaimAttributes\n        {\n            <#\n            The buffer receives a CLAIM_SECURITY_ATTRIBUTES_INFORMATION structure that contains the user claims associated with the token.\n                CLAIM_SECURITY_ATTRIBUTES_INFORMATION (Structure)\n                CLAIM_SECURITY_ATTRIBUTE_V1 (Structure)\n                CLAIM_SECURITY_ATTRIBUTE_FQBN_VALUE (Structure)\n                CLAIM_SECURITY_ATTRIBUTE_OCTET_STRING_VALUE (Structure)\n            #>\n            <#\n            $AttributeInformation = $TokenPtr -as $CLAIM_SECURITY_ATTRIBUTES_INFORMATION\n                \n            if($AttributeInformation.AttributeCount -ne 0)\n            {\n\n            }\n            #>\n            throw [System.NotImplementedException]\"The $($TokenInformationClass) class is not implemented yet.\"\n        }\n        TokenDeviceClaimAttributes\n        {\n            <#\n            The buffer receives a CLAIM_SECURITY_ATTRIBUTES_INFORMATION structure that contains the device claims associated with the token.\n                CLAIM_SECURITY_ATTRIBUTES_INFORMATION (Structure)\n                CLAIM_SECURITY_ATTRIBUTE_V1 (Structure)\n                CLAIM_SECURITY_ATTRIBUTE_FQBN_VALUE (Structure)\n                CLAIM_SECURITY_ATTRIBUTE_OCTET_STRING_VALUE (Structure)\n            #>\n            <#\n            $AttributeInformation = $TokenPtr -as $CLAIM_SECURITY_ATTRIBUTES_INFORMATION\n                \n            if($AttributeInformation.AttributeCount -ne 0)\n            {\n\n            }\n            #>\n            throw [System.NotImplementedException]\"The $($TokenInformationClass) class is not implemented yet.\"\n        }\n        TokenDeviceGroups\n        {\n            <#\n            The buffer receives a TOKEN_GROUPS structure that contains the device groups that are associated with the token.\n                TOKEN_GROUPS (Structure)\n                SID_AND_ATTRIBUTES (Structure)\n            #>\n            #Write-Output ($TokenPtr -as $TOKEN_GROUPS)\n            $TokenGroups = ($TokenPtr -as $TOKEN_GROUPS)\n\n            for($i = 0; $i -lt $TokenGroups.GroupCount; $i++)\n            {\n                $obj = New-Object -TypeName psobject\n\n                $obj | Add-Member -MemberType NoteProperty -Name Sid -Value (ConvertSidToStringSid -SidPointer $TokenGroups.Groups[$i].Sid)\n                $obj | Add-Member -MemberType NoteProperty -Name Attributes -Value $TokenGroups.Groups[$i].Attributes\n\n                Write-Output $obj\n            }\n        }\n        TokenRestrictedDeviceGroups\n        {\n            <#\n            The buffer receives a TOKEN_GROUPS structure that contains the restricted device groups that are associated with the token.\n                TOKEN_GROUPS (Structure)\n                SID_AND_ATTRIBUTES (Structure)\n            #>\n            $TokenGroups = ($TokenPtr -as $TOKEN_GROUPS)\n\n            for($i = 0; $i -lt $TokenGroups.GroupCount; $i++)\n            {\n                $obj = New-Object -TypeName psobject\n\n                $obj | Add-Member -MemberType NoteProperty -Name Sid -Value (ConvertSidToStringSid -SidPointer $TokenGroups.Groups[$i].Sid)\n                $obj | Add-Member -MemberType NoteProperty -Name Attributes -Value $TokenGroups.Groups[$i].Attributes\n\n                Write-Output $obj\n            }\n        }\n    }\n\n    [System.Runtime.InteropServices.Marshal]::FreeHGlobal($TokenPtr)\n}\n\nfunction GlobalGetAtomName\n{\n    <#\n    .SYNOPSIS\n\n    Retrieves a copy of the character string associated with the specified global atom.\n\n    .DESCRIPTION\n\n    The string returned for an integer atom (an atom whose value is in the range 0x0001 to 0xBFFF) is a null-terminated string in which the first character is a pound sign (#) and the remaining characters represent the unsigned integer atom value.\n\n    .PARAMETER AtomIndex\n\n    The global atom (index) associated with the character string to be retrieved.\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: PSReflect\n    Optional Dependencies: None\n\n    (func kernel32 GlobalGetAtomName ([UInt32]) @(\n        [UInt16],  #_In_  ATOM   nAtom\n        [string].MakeByRefType(), #_Out_ LPTSTR lpBuffer\n        [UInt16]   #_In_  int    nSize\n    ) -EntryPoint GlobalGetAtomName -SetLastError)\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/ms649063(v=vs.85).aspx\n\n    .EXAMPLE\n\n    #>\n\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [UInt16]\n        $AtomIndex\n    )\n\n    $AtomName = [System.Runtime.InteropServices.Marshal]::AllocHGlobal(1024)\n\n    $SUCCESS = $kernel32::GlobalGetAtomName($AtomIndex, $AtomName, 1024); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n\n    if($SUCCESS -eq 0)\n    {\n        throw \"[GlobalGetAtomName]: Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n\n    Write-Output ([System.Runtime.InteropServices.Marshal]::PtrToStringUni($AtomName))\n}\n\nfunction ImpersonateLoggedOnUser\n{\n    <#\n    .SYNOPSIS\n\n    The ImpersonateLoggedOnUser function lets the calling thread impersonate the security context of a logged-on user. The user is represented by a token handle.\n\n    .DESCRIPTION\n\n    The impersonation lasts until the thread exits or until it calls RevertToSelf.\n    \n    The calling thread does not need to have any particular privileges to call ImpersonateLoggedOnUser.\n    \n    If the call to ImpersonateLoggedOnUser fails, the client connection is not impersonated and the client request is made in the security context of the process. If the process is running as a highly privileged account, such as LocalSystem, or as a member of an administrative group, the user may be able to perform actions they would otherwise be disallowed. Therefore, it is important to always check the return value of the call, and if it fails, raise an error; do not continue execution of the client request.\n    \n    All impersonate functions, including ImpersonateLoggedOnUser allow the requested impersonation if one of the following is true:\n    - The requested impersonation level of the token is less than SecurityImpersonation, such as SecurityIdentification or SecurityAnonymous.\n    - The caller has the SeImpersonatePrivilege privilege.\n    - A process (or another process in the caller's logon session) created the token using explicit credentials through LogonUser or LsaLogonUser function.\n    - The authenticated identity is same as the caller.\n    \n    Windows XP with SP1 and earlier:  The SeImpersonatePrivilege privilege is not supported.\n\n    .PARAMETER TokenHandle\n\n    A handle to a primary or impersonation access token that represents a logged-on user. This can be a token handle returned by a call to LogonUser, CreateRestrictedToken, DuplicateToken, DuplicateTokenEx, OpenProcessToken, or OpenThreadToken functions. If hToken is a handle to a primary token, the token must have TOKEN_QUERY and TOKEN_DUPLICATE access. If hToken is a handle to an impersonation token, the token must have TOKEN_QUERY and TOKEN_IMPERSONATE access.\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: PSReflect\n    Optional Dependencies: None\n\n    (func advapi32 ImpersonateLoggedOnUser ([bool]) @(\n        [IntPtr] #_In_ HANDLE hToken\n    ) -EntryPoint ImpersonateLoggedOnUser -SetLastError)\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa378612(v=vs.85).aspx\n\n    .EXAMPLE\n\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $TokenHandle\n    )\n\n    $SUCCESS = $Advapi32::ImpersonateLoggedOnUser($TokenHandle); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n    \n    if(-not $SUCCESS)\n    {\n        throw \"ImpersonateLoggedOnUser Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n}\n\nfunction LookupPrivilegeName\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [UInt32]\n        $PrivilegeValue\n    )\n\n    $L = [Activator]::CreateInstance($LUID)\n    $L.LowPart = $PrivilegeValue\n\n    $lpLuid = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($LUID::GetSize())\n    [System.Runtime.InteropServices.Marshal]::StructureToPtr($L, $lpLuid, $true)\n\n    $lpName = New-Object -TypeName System.Text.StringBuilder\n\n    $cchName = 0\n\n    $SUCCESS = $Advapi32::LookupPrivilegeName($null, $lpLuid, $lpName, [ref]$cchName); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n\n    $lpName.EnsureCapacity($cchName + 1) | Out-Null\n\n    $SUCCESS = $Advapi32::LookupPrivilegeName($null, $lpLuid, $lpName, [ref]$cchName); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n    \n    if(-not $SUCCESS) \n    {\n        Write-Error \"[LookupPrivilegeName] Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n\n    Write-Output ($lpName.ToString())\n}\n\nfunction LookupPrivilegeDisplayName\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Privilege\n    )\n\n    $lpDisplayName = New-Object -TypeName System.Text.StringBuilder\n\n    $cchDisplayName = 0\n    $lpLanguageId = 0\n\n    $SUCCESS = $Advapi32::LookupPrivilegeDisplayName($null, $Privilege, $lpDisplayName, [ref]$cchDisplayName, [ref]$lpLanguageId)\n\n    $lpDisplayName.EnsureCapacity($cchDisplayName + 1) | Out-Null\n\n    $SUCCESS = $Advapi32::LookupPrivilegeDisplayName($null, $Privilege, $lpDisplayName, [ref]$cchDisplayName, [ref]$lpLanguageId); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n    \n    if(-not $SUCCESS) \n    {\n        Write-Error \"[LookupPrivilegeDisplayName] Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n\n    Write-Output ($lpDisplayName.ToString())\n}\n\nfunction LsaCallAuthenticationPackage\n{\n    <#\n    .SYNOPSIS\n\n    The LsaCallAuthenticationPackage function is used by a logon application to communicate with an authentication package.\n    \n    This function is typically used to access services provided by the authentication package.\n\n    .DESCRIPTION\n\n    Logon applications can call LsaCallAuthenticationPackage to communicate with an authentication package. There are several reasons why an application may do this:\n    \n    - To implement multiple-message authentication protocols, such as the NTLM Challenge-Response protocol.\n    - To pass state change information to the authentication package. For example, the NTLM might notify the MSV1_0 package that a previously unreachable domain controller is now reachable. The authentication package would then re-logon any users logged on to that domain controller.\n    \n    Typically, this function is used to exchange information with a custom authentication package. This function is not needed by an application that is using one of the authentication packages supplied with Windows, such as MSV1_0 or Kerberos.\n    \n    You must call LsaCallAuthenticationPackage to clean up PKINIT device credentials for LOCAL_SYSTEM and NETWORK_SERVICE. When there is no PKINIT device credential, a successful call does no operation. When there is a PKINIT device credential, a successful call cleans up the PKINIT device credential so that only the password credential remains.\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: None\n    Optional Dependencies: None\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa378261(v=vs.85).aspx\n\n    .EXAMPLE\n\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $LsaHandle,\n\n        [Parameter()]\n        [ValidateSet('MSV1_0_PACKAGE_NAME', 'MICROSOFT_KERBEROS_NAME_A', 'NEGOSSP_NAME_A', 'NTLMSP_NAME_A')]\n        [string]\n        $AuthenticationPackageName = 'MICROSOFT_KERBEROS_NAME_A',\n\n        [Parameter(Mandatory = $true)]\n        [UInt32]\n        $LogonId\n    )\n\n    <#\n    (func secur32 LsaCallAuthenticationPackage ([UInt32]) @(\n        [IntPtr],                                  #_In_  HANDLE    LsaHandle\n        [UInt64],                                  #_In_  ULONG     AuthenticationPackage\n        $KERB_RETRIEVE_TKT_REQUEST.MakeByRefType(),#_In_  PVOID     ProtocolSubmitBuffer\n        [UInt64],                                  #_In_  ULONG     SubmitBufferLength\n        [IntPtr],                                  #_Out_ PVOID     *ProtocolReturnBuffer\n        [UInt64].MakeByRefType(),                  #_Out_ PULONG    *ReturnBufferLength\n        [UInt32].MakeByRefType()                   #_Out_ PNTSTATUS ProtocolStatus\n    ))\n    #>\n\n    $AuthenticationPackage = LsaLookupAuthenticationPackage -LsaHandle $LsaHandle -PackageName $AuthenticationPackageName\n\n    switch($AuthenticationPackageName)\n    {\n        MSV1_0_PACKAGE_NAME\n        {\n            throw New-Object -TypeName System.NotImplementedException(\"MSV1_0_PACKAGE_NAME Package has not been implemented yet.\")\n        }\n        MICROSOFT_KERBEROS_NAME_A\n        {\n            # Request information about all of the cached tickets for the specified user logon session\n            <#\n            $KERB_QUERY_TKT_CACHE_REQUEST = struct $Mod Kerberos.KERB_QUERY_TKT_CACHE_REQUEST @{\n                MessageType = field 0 $KERB_PROTOCOL_MESSAGE_TYPE\n                LogonId = field 1 $LUID\n            }\n            #>\n            $ProtocolSubmitBuffer = [Activator]::CreateInstance($KERB_QUERY_TKT_CACHE_REQUEST)\n            $ProtocolSubmitBuffer.MessageType = $KERB_PROTOCOL_MESSAGE_TYPE::KerbQueryTicketCacheMessage\n            $LogonIdLuid = [Activator]::CreateInstance($LUID)\n            $LogonIdLuid.LowPart = $LogonId\n            $LogonIdLuid.HighPart = 0\n            $ProtocolSubmitBuffer.LogonId = $LogonIdLuid\n\n            $ProtocolReturnBuffer = [IntPtr]::Zero\n            $ReturnBufferLength = [UInt64]0\n            $ProtocolStatus = [UInt32]0 \n\n            $SUCCESS = $Secur32::LsaCallAuthenticationPackage_KERB_QUERY_TKT_CACHE($LsaHandle, $AuthenticationPackage, [ref]$ProtocolSubmitBuffer, $KERB_RETRIEVE_TKT_REQUEST::GetSize(), [ref]$ProtocolReturnBuffer, [ref]$ReturnBufferLength, [ref]$ProtocolStatus)\n\n            if($SUCCESS -eq 0)\n            {\n                if($ProtocolStatus -eq 0)\n                {\n                    $Response = $ProtocolReturnBuffer -as $KERB_QUERY_TKT_CACHE_RESPONSE\n\n                    for($i = 0; $i -lt $Response.CountOfTickets; $i++)\n                    {\n                        $currentTicketPtr = [IntPtr]::Add($ProtocolReturnBuffer, (8 + ($i * $KERB_TICKET_CACHE_INFO::GetSize())))\n                        $data = $currentTicketPtr -as $KERB_TICKET_CACHE_INFO\n                            \n                        $StartTime = [DateTime]::FromFileTime($data.StartTime)\n                        $EndTime = [DateTime]::FromFileTime($data.EndTime)\n                        [timespan]$TicketLength = $EndTime.Subtract($StartTime)\n\n                        $props = @{\n                            ServerName = ([System.Runtime.InteropServices.Marshal]::PtrToStringAuto($data.ServerName.Buffer, $data.ServerName.Length / 2))\n                            RealmName = ([System.Runtime.InteropServices.Marshal]::PtrToStringAuto($data.RealmName.Buffer, $data.RealmName.Length / 2))\n                            StartTime = $StartTime\n                            EndTime = $EndTime\n                            TicketLength = $TicketLength\n                            RenewTime = ([datetime]::FromFileTime($data.RenewTime))\n                            EncryptionType = ($data.EncryptionType -as $KERB_ENCRYPTION_TYPE).ToString()\n                            TicketFlags = ($data.TicketFlags -as $KERB_TICKET_FLAGS).ToString()\n                        }\n\n                        Write-Output $props\n                    }\n                }\n                else\n                {\n                    $WinErrorCode = LsaNtStatusToWinError -NtStatus $ProtocolStatus\n                    $LastError = [ComponentModel.Win32Exception]$WinErrorCode\n                    throw \"LsaCallAuthenticationPackage Error: $($LastError.Message)\"\n                }\n            }\n            else\n            {\n                $WinErrorCode = LsaNtStatusToWinError -NtStatus $SUCCESS\n                $LastError = [ComponentModel.Win32Exception]$WinErrorCode\n                throw \"LsaCallAuthenticationPackage Error: $($LastError.Message)\"\n            }          \n        }\n        NEGOSSP_NAME_A\n        {\n            throw New-Object -TypeName System.NotImplementedException(\"NEGOSSP_NAME_A Package has not been implemented yet.\")\n        }\n        NTLMSP_NAME_A\n        {\n            throw New-Object -TypeName System.NotImplementedException(\"NTLMSP_NAME_A Package has not been implemented yet.\")\n        }\n    }\n}\n\nfunction LsaConnectUntrusted\n{\n    <#\n    .SYNOPSIS\n\n    The LsaConnectUntrusted function establishes an untrusted connection to the LSA server.\n\n    .DESCRIPTION\n\n    LsaConnectUntrusted returns a handle to an untrusted connection; it does not verify any information about the caller. The handle should be closed using the LsaDeregisterLogonProcess function.\n    \n    If your application simply needs to query information from authentication packages, you can use the handle returned by this function in calls to LsaCallAuthenticationPackage and LsaLookupAuthenticationPackage.\n    \n    Applications with the SeTcbPrivilege privilege may create a trusted connection by calling LsaRegisterLogonProcess.\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: None\n    Optional Dependencies: None\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa378265(v=vs.85).aspx\n\n    .EXAMPLE\n\n    $hLsa = LsaConnectUntrusted\n    #>\n\n    param\n    (\n\n    )\n\n    <#\n    (func secur32 LsaConnectUntrusted ([UInt32]) @(\n        [IntPtr].MakeByRefType() #_Out_ PHANDLE LsaHandle\n    ))\n    #>\n    \n    $LsaHandle = [IntPtr]::Zero\n\n    $SUCCESS = $Secur32::LsaConnectUntrusted([ref]$LsaHandle)\n\n    if($SUCCESS -ne 0)\n    {\n        $WinErrorCode = LsaNtStatusToWinError -NtStatus $success\n        $LastError = [ComponentModel.Win32Exception]$WinErrorCode\n        throw \"LsaConnectUntrusted Error: $($LastError.Message)\"\n    }\n\n    Write-Output $LsaHandle\n}\n\nfunction LsaDeregisterLogonProcess\n{\n    <#\n    .SYNOPSIS\n\n    The LsaDeregisterLogonProcess function deletes the caller's logon application context and closes the connection to the LSA server.\n\n    .DESCRIPTION\n\n    If your logon application references the connection handle after calling the LsaDeregisterLogonProcess function, unexpected behavior can result.\n    \n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: None\n    Optional Dependencies: None\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa378269(v=vs.85).aspx\n\n    .EXAMPLE\n\n    $hLsa = LsaConnectUntrusted\n\n    #\n    # Do Somthing with the LSA Handle\n    #\n    \n    LsaDeregisterLogonProcess -LsaHandle $hLsa\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $LsaHandle\n    )\n\n    <#\n    (func secur32 LsaDeregisterLogonProcess ([UInt32]) @(\n        [IntPtr] #_In_ HANDLE LsaHandle\n    ))\n    #>\n\n    $SUCCESS = $Secur32::LsaDeregisterLogonProcess($LsaHandle)\n\n    if($SUCCESS -ne 0)\n    {\n        $WinErrorCode = LsaNtStatusToWinError -NtStatus $success\n        $LastError = [ComponentModel.Win32Exception]$WinErrorCode\n        throw \"LsaDeregisterLogonProcess Error: $($LastError.Message)\"\n    }\n}\n\nfunction LsaEnumerateLogonSessions\n{\n    <#\n    .SYNOPSIS\n\n    The LsaEnumerateLogonSessions function retrieves the set of existing logon session identifiers (LUIDs) and the number of sessions.\n\n    .DESCRIPTION\n\n    To retrieve information about the logon sessions returned by LsaEnumerateLogonSessions, call the LsaGetLogonSessionData function.\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: PSReflect, LsaNtStatusToWinError (Function)\n    Optional Dependencies: None\n\n    (func secur32 LsaEnumerateLogonSessions ([UInt32]) @(\n        [UInt64].MakeByRefType(), #_Out_ PULONG LogonSessionCount,\n        [IntPtr].MakeByRefType()  #_Out_ PLUID  *LogonSessionList\n    ) -EntryPoint LsaEnumerateLogonSessions)\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa378275(v=vs.85).aspx\n\n    .EXAMPLE\n\n    LsaEnumerateLogonSessions\n    8\n    2390553591808\n\n    .EXAMPLE\n\n    $SessionCount, $LogonSessionListPtr = LsaEnumerateLogonSessions\n    #>\n\n    $LogonSessionCount = [UInt64]0\n    $LogonSessionList = [IntPtr]::Zero\n\n    $SUCCESS = $Secur32::LsaEnumerateLogonSessions([ref]$LogonSessionCount, [ref]$LogonSessionList)\n\n    if($SUCCESS -ne 0)\n    {\n        $WinErrorCode = LsaNtStatusToWinError -NtStatus $success\n        $LastError = [ComponentModel.Win32Exception]$WinErrorCode\n        throw \"LsaEnumerateLogonSessions Error: $($LastError.Message)\"\n    }\n\n    $obj = New-Object -TypeName psobject\n\n    $obj | Add-Member -MemberType NoteProperty -Name SessionCount -Value $LogonSessionCount\n    $obj | Add-Member -MemberType NoteProperty -Name SessionListPointer -Value $LogonSessionList\n    \n    Write-Output $obj\n}\n\nfunction LsaFreeReturnBuffer\n{\n    <#\n    .SYNOPSIS\n\n    The LsaFreeReturnBuffer function frees the memory used by a buffer previously allocated by the LSA.\n\n    .DESCRIPTION\n\n    Some of the LSA authentication functions allocate memory buffers to hold returned information, for example, LsaLogonUser and LsaCallAuthenticationPackage. Your application should call LsaFreeReturnBuffer to free these buffers when they are no longer needed.\n\n    .PARAMETER Buffer\n\n    Pointer to the buffer to be freed.\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: PSReflect, LsaNtStatusToWinError (Function)\n    Optional Dependencies: None\n\n    (func secur32 LsaFreeReturnBuffer ([UInt32]) @(\n        [IntPtr] #_In_ PVOID Buffer\n    ) -EntryPoint LsaFreeReturnBuffer)\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa378279(v=vs.85).aspx\n\n    .EXAMPLE\n\n    LsaFreeReturnBuffer -Buffer $Buffer\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $Buffer\n    )\n\n    $SUCCESS = $Secur32::LsaFreeReturnBuffer($Buffer)\n\n    if($SUCCESS -ne 0)\n    {\n        $WinErrorCode = LsaNtStatusToWinError -NtStatus $success\n        $LastError = [ComponentModel.Win32Exception]$WinErrorCode\n        throw \"LsaFreeReturnBuffer Error: $($LastError.Message)\"\n    }\n}\n\nfunction LsaGetLogonSessionData\n{\n    <#\n    .SYNOPSIS\n\n    The LsaGetLogonSessionData function retrieves information about a specified logon session.\n\n    .DESCRIPTION\n\n    .Parameter LuidPtr\n\n    .Parameter SessionCount\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: PSReflect, LsaFreeReturnBuffer (Function), LsaNtStatusToWinError (Function), SECURITY_LOGON_SESSION_DATA (Structure), LUID (Structure), LSA_UNICODE_STRING (Structure), LSA_LAST_INTER_LOGON_INFO (Structure), SecurityEntity (Enumeration), SECURITY_LOGON_TYPE (Enumeration)\n    Optional Dependencies: None\n\n    (func secur32 LsaGetLogonSessionData ([UInt32]) @(\n        [IntPtr],                #_In_  PLUID                        LogonId,\n        [IntPtr].MakeByRefType() #_Out_ PSECURITY_LOGON_SESSION_DATA *ppLogonSessionData\n    ) -EntryPoint LsaGetLogonSessionData)\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa378290(v=vs.85).aspx\n\n    .EXAMPLE\n\n    $SessionCount, $LogonSessionListPtr = LsaEnumerateLogonSessions\n    LsaGetLogonSessionData -LuidPtr $LogonSessionListPtr -SessionCount $SessionCount\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $LuidPtr,\n\n        [Parameter(Mandatory = $true)]\n        [UInt32]\n        $SessionCount\n    )\n\n    $CurrentLuidPtr = $LuidPtr\n\n    for($i = 0; $i -lt $SessionCount; $i++)\n    {\n        $sessionDataPtr = [IntPtr]::Zero\n        $SUCCESS = $Secur32::LsaGetLogonSessionData($CurrentLuidPtr, [ref]$sessionDataPtr)\n\n        if($SUCCESS -ne 0)\n        {\n            $WinErrorCode = LsaNtStatusToWinError -NtStatus $success\n            $LastError = [ComponentModel.Win32Exception]$WinErrorCode\n            throw \"LsaGetLogonSessionData Error: $($LastError.Message)\"\n        }\n\n        try\n        {\n            $sessionData = $sessionDataPtr -as $SECURITY_LOGON_SESSION_DATA\n\n            $props = @{\n                LogonId = $sessionData.LogonId.LowPart\n                UserName = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($sessionData.Username.Buffer, $sessionData.Username.Length / 2)\n                LogonDomain = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($sessionData.LogonDomain.Buffer, $sessionData.LognDomain.Length / 2)\n                AuthenticationPackage = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($sessionData.AuthenticationPackage.Buffer, $sessionData.AuthenticationPackage.Length / 2)\n                LogonType = ($sessionData.LogonType -as $SECURITY_LOGON_TYPE).ToString()\n                Session = $sessionData.Session\n                Sid = (New-Object -TypeName System.Security.Principal.SecurityIdentifier($sessionData.PSiD)).ToString()\n                LogonTime = [datetime]::FromFileTime($sessionData.LogonTime)\n                LogonServer = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($sessionData.LogonServer.Buffer, $sessionData.LogonServer.Length / 2)\n                DnsDomainName = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($sessionData.DnsDomainName.Buffer, $sessionData.DnsDomainName.Length / 2)\n                Upn =  [System.Runtime.InteropServices.Marshal]::PtrToStringUni($sessionData.Upn.Buffer, $sessionData.Upn.Length / 2)\n                UserFlags = $sessionData.UserFlags\n                LastSuccessfulLogon = $sessionData.LastLogonInfo.LastSuccessfulLogon\n                LastFailedLogon = $sessionData.LastLogonInfo.LastFailedLogon\n                FailedAttemptCountSinceLastSuccessfulLogon = $sessionData.LastLogonInfo.FailedAttemptCountSinceLastSuccessfulLogon\n                LogonScript = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($sessionData.LogonScript.Buffer, $sessionData.LogonScript.Length / 2)\n                ProfilePath = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($sessionData.ProfilePath.Buffer, $sessionData.ProfilePath.Length / 2)\n                HomeDirectory = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($sessionData.HomeDirectory.Buffer, $sessionData.HomeDirectory.Length / 2)\n                HomeDirectoryDrive = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($sessionData.HomeDirectoryDrive.Buffer, $sessionData.HomeDirectoryDrive.Length / 2)\n                LogoffTime = $sessionData.LogoffTime\n                KickOffTime = $sessionData.KickOffTime\n                PasswordLastSet = [datetime]::FromFileTime($sessionData.PasswordLastSet)\n                PasswordCanChange = [datetime]::FromFileTime($sessionData.PasswordCanChange)\n                PasswordMustChange = $sessionData.PasswordMustChange\n            }\n             \n            Write-Output $props       \n        }\n        catch\n        {\n\n        }\n\n        LsaFreeReturnBuffer -Buffer $sessionDataPtr\n        $CurrentLuidPtr = [IntPtr]($CurrentLuidPtr.ToInt64() + $LUID::GetSize())\n    }\n}\n\nfunction LsaLookupAuthenticationPackage\n{\n    <#\n    .SYNOPSIS\n\n    The LsaLookupAuthenticationPackage function obtains the unique identifier of an authentication package.\n\n    .DESCRIPTION\n\n    The authentication package identifier is used in calls to authentication functions such as LsaLogonUser and LsaCallAuthenticationPackage.\n\n    .PARAMETER LsaHandle\n\n    Handle obtained from a previous call to LsaRegisterLogonProcess or LsaConnectUntrusted.\n\n    .PARAMETER PackageName\n\n    Specifies the name of the authentication package. Supported packages are 'MSV1_0_PACKAGE_NAME', 'MICROSOFT_KERBEROS_NAME_A', 'NEGOSSP_NAME_A', and 'NTLMSP_NAME_A'.\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: None\n    Optional Dependencies: None\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa378297(v=vs.85).aspx\n\n    .EXAMPLE\n\n    $hLsa = LsaConnectUntrusted\n\n    LsaLookupAuthenticationPackage -LsaHandle $hLsa -PackageName MICROSOFT_KERBEROS_NAME_A\n    2\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $LsaHandle,\n\n        [Parameter(Mandatory = $true)]\n        [ValidateSet('MSV1_0_PACKAGE_NAME', 'MICROSOFT_KERBEROS_NAME_A', 'NEGOSSP_NAME_A', 'NTLMSP_NAME_A')]\n        [string]\n        $PackageName\n    )\n\n    <#\n    (func secur32 LsaLookupAuthenticationPackage ([UInt32]) @(\n        [IntPtr],                           #_In_  HANDLE      LsaHandle,\n        $LSA_UNICODE_STRING.MakeByRefType() #_In_  PLSA_STRING PackageName,\n        [UInt64].MakeByRefType()            #_Out_ PULONG      AuthenticationPackage\n    ))\n    #>\n\n    switch($PackageName)\n    {\n        MSV1_0_PACKAGE_NAME {$authPackageName = 'NTLM'; break}\n        MICROSOFT_KERBEROS_NAME_A {$authPackageName = 'Kerberos'; break}\n        NEGOSSP_NAME_A {$authPackageName = 'Negotiate'; break}\n        NTLMSP_NAME_A {$authPackageName = 'NTLM'; break}\n    }\n\n    $authPackageArray = [System.Text.Encoding]::ASCII.GetBytes($authPackageName)\n    [int]$size = $authPackageArray.Length\n    [IntPtr]$pnt = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($size) \n    [System.Runtime.InteropServices.Marshal]::Copy($authPackageArray, 0, $pnt, $authPackageArray.Length)\n    \n    $lsaString = [Activator]::CreateInstance($LSA_STRING)\n    $lsaString.Length = [UInt16]$authPackageArray.Length\n    $lsaString.MaximumLength = [UInt16]$authPackageArray.Length\n    $lsaString.Buffer = $pnt\n    \n    $AuthenticationPackage = [UInt64]0\n\n    $SUCCESS = $Secur32::LsaLookupAuthenticationPackage($LsaHandle, [ref]$lsaString, [ref]$AuthenticationPackage)\n    \n    if($SUCCESS -ne 0)\n    {\n        $WinErrorCode = LsaNtStatusToWinError -NtStatus $success\n        $LastError = [ComponentModel.Win32Exception]$WinErrorCode\n        throw \"LsaLookupAuthenticationPackage Error: $($LastError.Message)\"\n    }\n\n    [System.Runtime.InteropServices.Marshal]::FreeHGlobal($pnt)\n\n    Write-Output $AuthenticationPackage\n}\n\nfunction LsaNtStatusToWinError\n{\n    <#\n    .SYNOPSIS\n\n    The LsaNtStatusToWinError function converts an NTSTATUS code returned by an LSA function to a Windows error code.\n\n    .PARAMETER NtStatus\n\n    An NTSTATUS code returned by an LSA function call. This value will be converted to a System error code.\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: PSReflect\n    Optional Dependencies: None\n\n    (func advapi32 LsaNtStatusToWinError ([UInt64]) @(\n        [UInt32] #_In_ NTSTATUS Status\n    ) -EntryPoint LsaNtStatusToWinError)\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/ms721800(v=vs.85).aspx\n\n    .EXAMPLE\n    #>\n\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [UInt32]\n        $NtStatus\n    )\n\n    $STATUS = $Advapi32::LsaNtStatusToWinError($NtStatus)\n\n    Write-Output $STATUS\n}\n\nfunction LsaRegisterLogonProcess\n{\n    <#\n    .SYNOPSIS\n\n    The LsaLookupAuthenticationPackage function obtains the unique identifier of an authentication package.\n\n    .DESCRIPTION\n\n    The authentication package identifier is used in calls to authentication functions such as LsaLogonUser and LsaCallAuthenticationPackage.\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: None\n    Optional Dependencies: None\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa378297(v=vs.85).aspx\n\n    .EXAMPLE\n\n    $hLsa = LsaRegisterLogonProcess\n\n    #>\n\n    <#\n    (func secur32 LsaRegisterLogonProcess ([UInt32]) @(\n        $LSA_STRING.MakeByRefType() #_In_  PLSA_STRING           LogonProcessName,\n        [IntPtr].MakeByRefType()    #_Out_ PHANDLE               LsaHandle,\n        [UInt64].MakeByRefType()    #_Out_ PLSA_OPERATIONAL_MODE SecurityMode\n    ))\n    #>\n\n    $lsaStringArray = [System.Text.Encoding]::ASCII.GetBytes(\"INVOKE-IR\")\n    [int]$size = $lsaStringArray.Length\n    [IntPtr]$pnt = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($size) \n    [System.Runtime.InteropServices.Marshal]::Copy($lsaStringArray, 0, $pnt, $lsaStringArray.Length)\n    \n    $lsaString = [Activator]::CreateInstance($LSA_STRING)\n    $lsaString.Length = [UInt16]$lsaStringArray.Length\n    $lsaString.MaximumLength = [UInt16]$lsaStringArray.Length\n    $lsaString.Buffer = $pnt\n\n    $LsaHandle = [IntPtr]::Zero\n    $SecurityMode = [UInt64]0\n\n    $SUCCESS = $Secur32::LsaRegisterLogonProcess([ref]$lsaString, [ref]$LsaHandle, [ref]$SecurityMode)\n\n    if($SUCCESS -ne 0)\n    {\n        $WinErrorCode = LsaNtStatusToWinError -NtStatus $success\n        $LastError = [ComponentModel.Win32Exception]$WinErrorCode\n        throw \"LsaRegisterLogonProcess Error: $($LastError.Message)\"\n    }\n\n    Write-Output $LsaHandle\n}\n\nfunction NtQueryInformationThread\n{\n    <#\n    .SYNOPSIS\n\n    Retrieves information about the specified thread.\n\n    .PARAMETER ThreadHandle\n\n    A handle to the thread about which information is being requested.\n\n    .PARAMETER ThreadInformationClass\n\n    If this parameter is the ThreadIsIoPending value of the THREADINFOCLASS enumeration, the function determines whether the thread has any I/O operations pending.\n    \n    Use the public function GetThreadIOPendingFlag instead to obtain this information.\n    \n    If this parameter is the ThreadQuerySetWin32StartAddress value of the THREADINFOCLASS enumeration, the function returns the start address of the thread. Note that on versions of Windows prior to Windows Vista, the returned start address is only reliable before the thread starts running.\n    \n    If this parameter is the ThreadSubsystemInformation value of the THREADINFOCLASS enumeration, the function retrieves a SUBSYSTEM_INFORMATION_TYPE value indicating the subsystem type of the thread. The buffer pointed to by the ThreadInformation parameter should be large enough to hold a single SUBSYSTEM_INFORMATION_TYPE enumeration.\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: PSReflect, THREADINFOCLASS (Enumeration)\n    Optional Dependencies: None\n\n    (func ntdll NtQueryInformationThread ([Int32]) @(\n        [IntPtr], #_In_      HANDLE          ThreadHandle,\n        [Int32],  #_In_      THREADINFOCLASS ThreadInformationClass,\n        [IntPtr], #_Inout_   PVOID           ThreadInformation,\n        [Int32],  #_In_      ULONG           ThreadInformationLength,\n        [IntPtr]  #_Out_opt_ PULONG          ReturnLength\n    ) -EntryPoint NtQueryInformationThread)\n        \n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/ms684283(v=vs.85).aspx\n\n    .EXAMPLE\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $ThreadHandle,\n\n        [Parameter(Mandatory = $true)]\n        [ValidateSet('ThreadBasicInformation','ThreadTimes','ThreadPriority','ThreadBasePriority','ThreadAffinityMask','ThreadImpersonationToken','ThreadDescriptorTableEntry','ThreadEnableAlignmentFaultFixup','ThreadEventPair_Reusable','ThreadQuerySetWin32StartAddress','ThreadZeroTlsCell','ThreadPerformanceCount','ThreadAmILastThread','ThreadIdealProcessor','ThreadPriorityBoost','ThreadSetTlsArrayAddress','ThreadIsIoPending','ThreadHideFromDebugger','ThreadBreakOnTermination','ThreadSwitchLegacyState','ThreadIsTerminated','ThreadLastSystemCall','ThreadIoPriority','ThreadCycleTime','ThreadPagePriority','ThreadActualBasePriority','ThreadTebInformation','ThreadCSwitchMon','ThreadCSwitchPmu','ThreadWow64Context','ThreadGroupInformation','ThreadUmsInformation','ThreadCounterProfiling','ThreadIdealProcessorEx','ThreadCpuAccountingInformation','ThreadSuspendCount','ThreadHeterogeneousCpuPolicy','ThreadContainerId','ThreadNameInformation','ThreadSelectedCpuSets','ThreadSystemThreadInformation','ThreadActualGroupAffinity','ThreadDynamicCodePolicyInfo','ThreadExplicitCaseSensitivity','ThreadWorkOnBehalfTicket','ThreadSubsystemInformation','ThreadDbgkWerReportActive','ThreadAttachContainer','MaxThreadInfoClass')]\n        [string]\n        $ThreadInformationClass\n    )\n    \n    $buf = [System.Runtime.InteropServices.Marshal]::AllocHGlobal([IntPtr]::Size)\n\n    $Success = $Ntdll::NtQueryInformationThread($ThreadHandle, $THREADINFOCLASS::$ThreadInformationClass, $buf, [IntPtr]::Size, [IntPtr]::Zero); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n\n    if(-not $Success) \n    {\n        Write-Debug \"[NtQueryInformationThread] Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n    \n    switch($ThreadInformationClass)\n    {\n        ThreadBasicInformation\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadTimes\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadPriority\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadBasePriority\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadAffinityMask\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadImpersonationToken\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadDescriptorTableEntry\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadEnableAlignmentFaultFixup\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadEventPair_Reusable\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadQuerySetWin32StartAddress\n        {\n            Write-Output ([System.Runtime.InteropServices.Marshal]::ReadIntPtr($buf))\n        }\n        ThreadZeroTlsCell\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadPerformanceCount\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadAmILastThread\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadIdealProcessor\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadPriorityBoost\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadSetTlsArrayAddress\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadIsIoPending\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadHideFromDebugger\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadBreakOnTermination\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadSwitchLegacyState\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadIsTerminated\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadLastSystemCall\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadIoPriority\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadCycleTime\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadPagePriority\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadActualBasePriority\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadTebInformation\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadCSwitchMon\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadCSwitchPmu\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadWow64Context\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadGroupInformation\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadUmsInformation\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadCounterProfiling\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadIdealProcessorEx\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadCpuAccountingInformation\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadSuspendCount\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadHeterogeneousCpuPolicy\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadContainerId\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadNameInformation\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadSelectedCpuSets\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadSystemThreadInformation\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadActualGroupAffinity\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadDynamicCodePolicyInfo\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadExplicitCaseSensitivity\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadWorkOnBehalfTicket\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadSubsystemInformation\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadDbgkWerReportActive\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        ThreadAttachContainer\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n        MaxThreadInfoClass\n        {\n            throw [System.NotImplementedException]\"The $($ThreadInformationClass) class is not implemented yet.\"\n        }\n    }\n}\n\nfunction OpenProcess\n{\n    <#\n    .SYNOPSIS\n\n    Opens an existing local process object.\n\n    .DESCRIPTION\n\n    To open a handle to another local process and obtain full access rights, you must enable the SeDebugPrivilege privilege.\n    The handle returned by the OpenProcess function can be used in any function that requires a handle to a process, such as the wait functions, provided the appropriate access rights were requested.\n    When you are finished with the handle, be sure to close it using the CloseHandle function.\n\n    .PARAMETER ProcessId\n\n    The identifier of the local process to be opened.\n    If the specified process is the System Process (0x00000000), the function fails and the last error code is ERROR_INVALID_PARAMETER. If the specified process is the Idle process or one of the CSRSS processes, this function fails and the last error code is ERROR_ACCESS_DENIED because their access restrictions prevent user-level code from opening them.\n\n    .PARAMETER DesiredAccess\n\n    The access to the process object. This access right is checked against the security descriptor for the process. This parameter can be one or more of the process access rights.\n    If the caller has enabled the SeDebugPrivilege privilege, the requested access is granted regardless of the contents of the security descriptor.\n\n    .PARAMETER InheritHandle\n\n    If this value is TRUE, processes created by this process will inherit the handle. Otherwise, the processes do not inherit this handle.\n\n    .NOTES\n    \n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: PSReflect, PROCESS_ACCESS (Enumeration)\n    Optional Dependencies: None\n\n    (func kernel32 OpenProcess ([IntPtr]) @(\n        [UInt32], #_In_ DWORD dwDesiredAccess\n        [bool],   #_In_ BOOL  bInheritHandle\n        [UInt32]  #_In_ DWORD dwProcessId\n    ) -EntryPoint OpenProcess -SetLastError)\n        \n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/ms684320(v=vs.85).aspx\n    \n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/ms684880(v=vs.85).aspx\n\n    .EXAMPLE\n    #>\n\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [UInt32]\n        $ProcessId,\n        \n        [Parameter(Mandatory = $true)]\n        [ValidateSet('PROCESS_TERMINATE','PROCESS_CREATE_THREAD','PROCESS_VM_OPERATION','PROCESS_VM_READ','PROCESS_VM_WRITE','PROCESS_DUP_HANDLE','PROCESS_CREATE_PROCESS','PROCESS_SET_QUOTA','PROCESS_SET_INFORMATION','PROCESS_QUERY_INFORMATION','PROCESS_SUSPEND_RESUME','PROCESS_QUERY_LIMITED_INFORMATION','DELETE','READ_CONTROL','WRITE_DAC','WRITE_OWNER','SYNCHRONIZE','PROCESS_ALL_ACCESS')]\n        [string[]]\n        $DesiredAccess,\n        \n        [Parameter()]\n        [bool]\n        $InheritHandle = $false\n    )\n\n    # Calculate Desired Access Value\n    $dwDesiredAccess = 0\n\n    foreach($val in $DesiredAccess)\n    {\n        $dwDesiredAccess = $dwDesiredAccess -bor $PROCESS_ACCESS::$val\n    }\n\n    $hProcess = $Kernel32::OpenProcess($dwDesiredAccess, $InheritHandle, $ProcessId); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n\n    if($hProcess -eq 0) \n    {\n        throw \"OpenProcess Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n    \n    Write-Output $hProcess\n}\n\nfunction OpenProcessToken\n{ \n    <#\n    .SYNOPSIS\n\n    The OpenProcessToken function opens the access token associated with a process.\n\n    .PARAMETER ProcessHandle\n\n    A handle to the process whose access token is opened. The process must have the PROCESS_QUERY_INFORMATION access permission.\n\n    .PARAMETER DesiredAccess\n\n    Specifies an access mask that specifies the requested types of access to the access token. These requested access types are compared with the discretionary access control list (DACL) of the token to determine which accesses are granted or denied.\n    For a list of access rights for access tokens, see Access Rights for Access-Token Objects.\n\n    .NOTES\n    \n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: PSReflect, TOKEN_ACCESS (Enumeration)\n    Optional Dependencies: None\n\n    (func advapi32 OpenProcessToken ([bool]) @(\n        [IntPtr],                #_In_  HANDLE  ProcessHandle\n        [UInt32],                #_In_  DWORD   DesiredAccess\n        [IntPtr].MakeByRefType() #_Out_ PHANDLE TokenHandle\n    ) -EntryPoint OpenProcessToken -SetLastError)\n        \n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa379295(v=vs.85).aspx\n    \n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa374905(v=vs.85).aspx\n\n    .EXAMPLE\n    #>\n\n    [OutputType([IntPtr])]\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $ProcessHandle,\n        \n        [Parameter(Mandatory = $true)]\n        [ValidateSet('TOKEN_ASSIGN_PRIMARY','TOKEN_DUPLICATE','TOKEN_IMPERSONATE','TOKEN_QUERY','TOKEN_QUERY_SOURCE','TOKEN_ADJUST_PRIVILEGES','TOKEN_ADJUST_GROUPS','TOKEN_ADJUST_DEFAULT','TOKEN_ADJUST_SESSIONID','DELETE','READ_CONTROL','WRITE_DAC','WRITE_OWNER','SYNCHRONIZE','STANDARD_RIGHTS_REQUIRED','TOKEN_ALL_ACCESS')]\n        [string[]]\n        $DesiredAccess  \n    )\n    \n    # Calculate Desired Access Value\n    $dwDesiredAccess = 0\n\n    foreach($val in $DesiredAccess)\n    {\n        $dwDesiredAccess = $dwDesiredAccess -bor $TOKEN_ACCESS::$val\n    }\n\n    $hToken = [IntPtr]::Zero\n    $Success = $Advapi32::OpenProcessToken($ProcessHandle, $dwDesiredAccess, [ref]$hToken); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n\n    if(-not $Success) \n    {\n        throw \"OpenProcessToken Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n    \n    Write-Output $hToken\n}\n\nfunction OpenThread\n{\n    <#\n    .SYNOPSIS\n\n    Opens an existing thread object.\n\n    .DESCRIPTION\n\n    The handle returned by OpenThread can be used in any function that requires a handle to a thread, such as the wait functions, provided you requested the appropriate access rights. The handle is granted access to the thread object only to the extent it was specified in the dwDesiredAccess parameter.\n    When you are finished with the handle, be sure to close it by using the CloseHandle function.\n\n    .PARAMETER ThreadId\n\n    The identifier of the thread to be opened.\n\n    .PARAMETER DesiredAccess\n\n    The access to the thread object. This access right is checked against the security descriptor for the thread. This parameter can be one or more of the thread access rights.\n    If the caller has enabled the SeDebugPrivilege privilege, the requested access is granted regardless of the contents of the security descriptor.\n\n    .PARAMETER InheritHandle\n\n    If this value is TRUE, processes created by this process will inherit the handle. Otherwise, the processes do not inherit this handle.\n    \n    .NOTES\n    \n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: PSReflect, THREAD_ACCESS (Enumeration)\n    Optional Dependencies: None\n\n    (func kernel32 OpenThread ([IntPtr]) @(\n        [UInt32], #_In_ DWORD dwDesiredAccess\n        [bool],   #_In_ BOOL  bInheritHandle\n        [UInt32]  #_In_ DWORD dwThreadId\n    ) -EntryPoint OpenThread -SetLastError)\n        \n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/ms684335(v=vs.85).aspx\n    \n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/ms686769(v=vs.85).aspx\n\n    .EXAMPLE\n    #>\n\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [UInt32]\n        $ThreadId,\n        \n        [Parameter(Mandatory = $true)]\n        [ValidateSet('THREAD_TERMINATE','THREAD_SUSPEND_RESUME','THREAD_GET_CONTEXT','THREAD_SET_CONTEXT','THREAD_SET_INFORMATION','THREAD_QUERY_INFORMATION','THREAD_SET_THREAD_TOKEN','THREAD_IMPERSONATE','THREAD_DIRECT_IMPERSONATION','THREAD_SET_LIMITED_INFORMATION','THREAD_QUERY_LIMITED_INFORMATION','DELETE','READ_CONTROL','WRITE_DAC','WRITE_OWNER','SYNCHRONIZE','THREAD_ALL_ACCESS')]\n        [string[]]\n        $DesiredAccess,\n        \n        [Parameter()]\n        [bool]\n        $InheritHandle = $false\n    )\n    \n    # Calculate Desired Access Value\n    $dwDesiredAccess = 0\n    \n    foreach($val in $DesiredAccess)\n    {\n        $dwDesiredAccess = $dwDesiredAccess -bor $THREAD_ACCESS::$val\n    }\n\n    $hThread = $Kernel32::OpenThread($dwDesiredAccess, $InheritHandle, $ThreadId); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n\n    if($hThread -eq 0) \n    {\n        throw \"OpenThread Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n    \n    Write-Output $hThread\n}\n\nfunction OpenThreadToken\n{\n    <#\n    .SYNOPSIS\n\n    The OpenThreadToken function opens the access token associated with a thread\n\n    .DESCRIPTION\n\n    Tokens with the anonymous impersonation level cannot be opened.\n    Close the access token handle returned through the Handle parameter by calling CloseHandle.\n\n    .PARAMETER ThreadHandle\n\n    A handle to the thread whose access token is opened.\n\n    .PARAMETER DesiredAccess\n\n    Specifies an access mask that specifies the requested types of access to the access token. These requested access types are reconciled against the token's discretionary access control list (DACL) to determine which accesses are granted or denied.\n\n    .PARAMETER OpenAsSelf\n\n    TRUE if the access check is to be made against the process-level security context.\n    FALSE if the access check is to be made against the current security context of the thread calling the OpenThreadToken function.\n    The OpenAsSelf parameter allows the caller of this function to open the access token of a specified thread when the caller is impersonating a token at SecurityIdentification level. Without this parameter, the calling thread cannot open the access token on the specified thread because it is impossible to open executive-level objects by using the SecurityIdentification impersonation level.\n\n    .NOTES\n    \n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: PSReflect, $TOKEN_ACCESS (Enumeration)\n    Optional Dependencies: None\n\n    (func advapi32 OpenThreadToken ([bool]) @(\n      [IntPtr],                #_In_  HANDLE  ThreadHandle\n      [UInt32],                #_In_  DWORD   DesiredAccess\n      [bool],                  #_In_  BOOL    OpenAsSelf\n      [IntPtr].MakeByRefType() #_Out_ PHANDLE TokenHandle\n    ) -EntryPoint OpenThreadToken -SetLastError)\n        \n    .LINK\n    \n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa379296(v=vs.85).aspx\n    \n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa374905(v=vs.85).aspx\n\n    .EXAMPLE\n    #>\n\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $ThreadHandle,\n        \n        [Parameter(Mandatory = $true)]\n        [ValidateSet('TOKEN_ASSIGN_PRIMARY','TOKEN_DUPLICATE','TOKEN_IMPERSONATE','TOKEN_QUERY','TOKEN_QUERY_SOURCE','TOKEN_ADJUST_PRIVILEGES','TOKEN_ADJUST_GROUPS','TOKEN_ADJUST_DEFAULT','TOKEN_ADJUST_SESSIONID','DELETE','READ_CONTROL','WRITE_DAC','WRITE_OWNER','SYNCHRONIZE','STANDARD_RIGHTS_REQUIRED','TOKEN_ALL_ACCESS')]\n        [string[]]\n        $DesiredAccess,\n        \n        [Parameter()]\n        [bool]\n        $OpenAsSelf = $false   \n    )\n    \n    # Calculate Desired Access Value\n    $dwDesiredAccess = 0\n\n    foreach($val in $DesiredAccess)\n    {\n        $dwDesiredAccess = $dwDesiredAccess -bor $TOKEN_ACCESS::$val\n    }\n\n    $hToken = [IntPtr]::Zero\n    $Success = $Advapi32::OpenThreadToken($ThreadHandle, $dwDesiredAccess, $OpenAsSelf, [ref]$hToken); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n\n    if(-not $Success) \n    {\n        throw \"[OpenThreadToken] Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n    \n    Write-Output $hToken\n}\n\nfunction RevertToSelf\n{\n    <#\n    .SYNOPSIS\n\n    The RevertToSelf function terminates the impersonation of a client application.\n\n    .DESCRIPTION\n\n    A process should call the RevertToSelf function after finishing any impersonation begun by using the DdeImpersonateClient, ImpersonateDdeClientWindow, ImpersonateLoggedOnUser, ImpersonateNamedPipeClient, ImpersonateSelf, ImpersonateAnonymousToken or SetThreadToken function.\n    \n    An RPC server that used the RpcImpersonateClient function to impersonate a client must call the RpcRevertToSelf or RpcRevertToSelfEx to end the impersonation.\n    \n    If RevertToSelf fails, your application continues to run in the context of the client, which is not appropriate. You should shut down the process if RevertToSelf fails.\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: None\n    Optional Dependencies: None\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa379317(v=vs.85).aspx\n\n    .EXAMPLE\n\n        RevertToSelf\n    #>\n\n    <#\n    (func advapi32 RevertToSelf ([bool]) @() -SetLastError)\n    #>\n\n    $SUCCESS = $Advapi32::RevertToSelf(); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n    \n    if(-not $SUCCESS)\n    {\n        throw \"[RevertToSelf] Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n}\n\nfunction Thread32First\n{\n    <#\n    .SYNOPSIS\n\n    Retrieves information about the first thread of any process encountered in a system snapshot.\n\n    .PARAMETER SnapshotHandle\n\n    A handle to the snapshot returned from a previous call to the CreateToolhelp32Snapshot function.\n\n    .NOTES\n    \n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: PSReflect\n    Optional Dependencies: None\n\n    (func kernel32 Thread32First ([bool]) @(\n        [IntPtr],                      #_In_    HANDLE          hSnapshot\n        $THREADENTRY32.MakeByRefType() #_Inout_ LPTHREADENTRY32 lpte\n    ) -EntryPoint Thread32First -SetLastError)\n        \n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/ms686728(v=vs.85).aspx\n\n    .EXAMPLE\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $SnapshotHandle\n    )\n        \n    $Thread = [Activator]::CreateInstance($THREADENTRY32)\n    $Thread.dwSize = $THREADENTRY32::GetSize()\n\n    $Success = $Kernel32::Thread32First($hSnapshot, [Ref]$Thread); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n\n    if(-not $Success) \n    {\n        Write-Debug \"Thread32First Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n    \n    Write-Output $Thread\n}\n\n#region Lee's Code...\nfunction Get-ServiceNameFromTag($ProcessId, $ServiceTag)\n{\n    $NTVersion = [System.Environment]::OSVersion.Version\n\n    if($NTVersion.Major -ge 6 -and $NTVersion.Minor -ge 1)\n    {\n        # Based off of https://wj32.org/wp/2010/03/30/howto-use-i_querytaginformation/\n        $ServiceTagQuery = [Activator]::CreateInstance($SC_SERVICE_TAG_QUERY)   # New-Object doesn't work on PSv2 for some reason.  Thanks @mattifestation! \n        $ServiceTagQuery.ProcessId = $ProcessId\n        $ServiceTagQuery.ServiceTag = $ServiceTag\n    \n        $Res = $Advapi32::I_QueryTagInformation([IntPtr]::Zero, $SC_SERVICE_TAG_QUERY_TYPE::ServiceNameFromTagInformation, [Ref] $ServiceTagQuery)\n        \n        if($Res -eq 0)\n        {\n            $ServiceStr = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($ServiceTagQuery.Buffer)\n            $ServiceStr\n        }\n        else {\n            #\"Error: $Res\"\n        }\n    }\n}\n\nfunction Get-Tcp4Connections\n{\n    Param\n    (\n        # Attempt to resolve the hostnames of each IP address\n        [switch]\n        $ResolveHostnames,\n\n        [switch]\n        $ReturnHashTables\n    )\n\n    $AF_INET = 2\n    $TableBufferSize = 0\n    $null = $iphlpapi::GetExtendedTcpTable([IntPtr]::Zero, [ref]$TableBufferSize, $true, $AF_INET, $TCP_TABLE_CLASS::TCP_TABLE_OWNER_MODULE_ALL, 0)\n    $TableBuffer = [Runtime.InteropServices.Marshal]::AllocHGlobal($TableBufferSize)\n    \n    try\n    {\n        $Ret = $iphlpapi::GetExtendedTcpTable($TableBuffer, [ref] $TableBufferSize, $true, $AF_INET, $TCP_TABLE_CLASS::TCP_TABLE_OWNER_MODULE_ALL, 0);\n        if ($Ret -ne 0)\n        {\n            Write-Error \"Failed to get TCP connection information. GetExtendedTcpTable's return code: $Ret\"\n            return\n        }\n        \n        $OwnerModuleTable  = $TableBuffer -as $MIB_TCPTABLE_OWNER_MODULE\n        $RowPtr = [IntPtr]($TableBuffer.ToInt64() + [Runtime.InteropServices.Marshal]::OffsetOf($MIB_TCPTABLE_OWNER_MODULE, \"Table\").ToInt64())\n        \n        for($i=0; $i -lt $OwnerModuleTable.NumEntries; $i++)\n        {\n            $TcpRow = $RowPtr -as $MIB_TCPROW_OWNER_MODULE\n\n            # Get the properties we want\n            $LocalAddr = [System.Net.IPAddress]$TcpRow.LocalAddr\n            $PortBytes = [System.BitConverter]::GetBytes($TcpRow.LocalPort)\n            $LocalPort = $PortBytes[0]*256 + $PortBytes[1]\n\n            $RemoteAddr = [System.Net.IPAddress]$TcpRow.RemoteAddr\n            $PortBytes = [System.BitConverter]::GetBytes($TcpRow.RemotePort)\n            $RemotePort = $PortBytes[0]*256 + $PortBytes[1]\n\n            $ServiceTag = $TcpRow.OwningModuleInfo[0]                \n\n            $RemoteHostname = $null\n            if($ResolveHostnames) {\n                try {\n                    $RemoteHostname = [System.Net.Dns]::GetHostEntry($RemoteAddr).HostName\n                }\n                catch {\n                    # Couldn't resolve the host name, so keep the IP\n                }\n            }\n\n            $Output = @{\n                LocalAddress = [string]$LocalAddr\n                LocalPort = $LocalPort\n                RemoteAddress = [string]$RemoteAddr\n                RemoteHostname = $RemoteHostname\n                RemotePort = $RemotePort\n                #Process = Get-Process -Id $TcpRow.OwningPid -ErrorAction SilentlyContinue\n                Process = (Get-Process -Id $TcpRow.OwningPid -ErrorAction SilentlyContinue).Name\n                ProcessId = $TcpRow.OwningPid\n                Protocol = \"TCP\"\n                State = $TcpRow.State.ToString()\n                Service = [string](Get-ServiceNameFromTag -ProcessId $TcpRow.OwningPid -ServiceTag $ServiceTag)\n            }\n\n            if($ReturnHashtables) {\n                $Output\n            } else {\n                New-Object PSObject -Property $Output \n            }\n\n            # Move to the next row in the TCP table\n            $RowPtr = [IntPtr]($RowPtr.ToInt64() + [Runtime.InteropServices.Marshal]::SizeOf($TcpRow))\n        }\n    }\n    catch\n    {\n        Write-Error $_\n    }\n    finally\n    {\n        [Runtime.InteropServices.Marshal]::FreeHGlobal($TableBuffer)\n    }\n}\n\nfunction Get-Tcp6Connections\n{\n    Param\n    (\n        # Attempt to resolve the hostnames of each IP address\n        [switch]\n        $ResolveHostnames,\n\n        [switch]\n        $ReturnHashTables\n    )\n\n    $AF_INET6 = 23\n    $TableBufferSize = 0\n        \n    $null = $iphlpapi::GetExtendedTcpTable([IntPtr]::Zero, [ref]$TableBufferSize, $true, $AF_INET6, $TCP_TABLE_CLASS::TCP_TABLE_OWNER_MODULE_ALL, 0)\n    $TableBuffer = [Runtime.InteropServices.Marshal]::AllocHGlobal($TableBufferSize)\n        \n    try\n    {\n        $Ret = $iphlpapi::GetExtendedTcpTable($TableBuffer, [ref] $TableBufferSize, $true, $AF_INET6, $TCP_TABLE_CLASS::TCP_TABLE_OWNER_MODULE_ALL, 0);\n            \n        if($Ret -eq 50)\n        {\n            # IPv6 is not supported\n            return\n        }\n        elseif ($Ret -ne 0)\n        {\n            Write-Error \"Failed to get TCP connection information. GetExtendedTcpTable's return code: $Ret\"\n            return\n        }\n        \n        $OwnerModuleTable  = $TableBuffer -as $MIB_TCP6TABLE_OWNER_MODULE\n        $RowPtr = [IntPtr]($TableBuffer.ToInt64() + [Runtime.InteropServices.Marshal]::OffsetOf($MIB_TCPTABLE_OWNER_MODULE, \"Table\").ToInt64())\n\n        for($i=0; $i -lt $OwnerModuleTable.NumEntries; $i++)\n        {\n            $TcpRow = $RowPtr -as $MIB_TCP6ROW_OWNER_MODULE\n            \n            # Get the properties we want\n            $LocalAddr = [System.Net.IPAddress]$TcpRow.LocalAddr\n            $PortBytes = [System.BitConverter]::GetBytes($TcpRow.LocalPort)\n            $LocalPort = $PortBytes[0]*256 + $PortBytes[1]\n            \n            $RemoteAddr = [System.Net.IPAddress]$TcpRow.RemoteAddr\n            $PortBytes = [System.BitConverter]::GetBytes($TcpRow.RemotePort)\n            $RemotePort = $PortBytes[0]*256 + $PortBytes[1]\n\n            $ServiceTag = $TcpRow.OwningModuleInfo[0]\n\n            $RemoteHostname = $null;\n            if($ResolveHostnames) {\n                try {\n                    $RemoteHostname = [System.Net.Dns]::GetHostEntry($RemoteAddr).HostName\n                }\n                catch {\n                    # Couldn't resolve the host name, so keep the IP\n                }\n            }\n\n            $Output = @{\n                LocalAddress = [string]$LocalAddr\n                LocalPort = $LocalPort\n                RemoteAddress = [string]$RemoteAddr\n                RemoteHostname = $RemoteHostname\n                RemotePort = $RemotePort\n                Process = (Get-Process -Id $TcpRow.OwningPid -ErrorAction SilentlyContinue).Name\n                ProcessId = $TcpRow.OwningPid\n                Protocol = \"TCP\"\n                State = $TcpRow.State.ToString()\n                Service = [string](Get-ServiceNameFromTag -ProcessId $TcpRow.OwningPid -ServiceTag $ServiceTag)\n            }\n\n            if($ReturnHashtables) {\n                $Output\n            } else {\n                New-Object PSObject -Property $Output \n            }\n\n            # Move to the next row in the TCP table\n            $RowPtr = [IntPtr]($RowPtr.ToInt64() + [Runtime.InteropServices.Marshal]::SizeOf($TcpRow))\n        }\n    }\n    catch\n    {\n        Write-Error $_\n    }\n    finally\n    {\n        [Runtime.InteropServices.Marshal]::FreeHGlobal($TableBuffer)\n    }\n}\n\nfunction Get-Udp4Connections\n{\n    Param\n    (\n        # Attempt to resolve the hostnames of each IP address\n        [switch]\n        $ResolveHostnames,\n\n        [switch]\n        $ReturnHashTables\n    )\n\n    $AF_INET = 2\n    $TableBufferSize = 0\n    $null = $iphlpapi::GetExtendedUdpTable([IntPtr]::Zero, [ref]$TableBufferSize, $true, $AF_INET, $UDP_TABLE_CLASS::UDP_TABLE_OWNER_MODULE, 0)\n    $TableBuffer = [Runtime.InteropServices.Marshal]::AllocHGlobal($TableBufferSize)\n\n    try\n    {\n        $Ret = $iphlpapi::GetExtendedUdpTable($TableBuffer, [ref] $TableBufferSize, $true, $AF_INET, $UDP_TABLE_CLASS::UDP_TABLE_OWNER_MODULE, 0);\n        if ($Ret -ne 0)\n        {\n            Write-Error \"Failed to get UDP connection information. GetExtendedUdpTable's return code: $Ret\"\n            return\n        }\n        \n        $OwnerModuleTable  = $TableBuffer -as $MIB_UDPTABLE_OWNER_MODULE\n        $RowPtr = [IntPtr]($TableBuffer.ToInt64() + [Runtime.InteropServices.Marshal]::OffsetOf($MIB_UDPTABLE_OWNER_MODULE, \"Table\").ToInt64())\n\n        for($i=0; $i -lt $OwnerModuleTable.NumEntries; $i++)\n        {\n            $UdpRow = $RowPtr -as $MIB_UDPROW_OWNER_MODULE\n\n            # Get the properties we want\n            $LocalAddr = [System.Net.IPAddress]$UdpRow.LocalAddr\n            $PortBytes = [System.BitConverter]::GetBytes($UdpRow.LocalPort)\n            $LocalPort = $PortBytes[0]*256 + $PortBytes[1]\n            $ServiceTag = $UdpRow.OwningModuleInfo[0]\n\n            $Output = @{\n                LocalAddress = [string]$LocalAddr\n                LocalPort = $LocalPort\n                Process = (Get-Process -Id $UdpRow.OwningPid -ErrorAction SilentlyContinue).Name\n                ProcessId = $UdpRow.OwningPid\n                Protocol = \"UDP\"\n                Service = [string](Get-ServiceNameFromTag -ProcessId $UdpRow.OwningPid -ServiceTag $ServiceTag)\n            }\n\n            if($ReturnHashtables) {\n                $Output\n            } else {\n                New-Object PSObject -Property $Output \n            }\n\n            # Move to the next row in the UDP table\n            $RowPtr = [IntPtr]($RowPtr.ToInt64() + ([Runtime.InteropServices.Marshal]::SizeOf($UdpRow)))\n        }\n    }\n    catch\n    {\n        Write-Error $_\n    }\n    finally\n    {\n        [Runtime.InteropServices.Marshal]::FreeHGlobal($TableBuffer)\n    }\n}\n\nfunction Get-Udp6Connections\n{\n    Param\n    (\n        # Attempt to resolve the hostnames of each IP address\n        [switch]\n        $ResolveHostnames,\n\n        [switch]\n        $ReturnHashTables\n    )\n\n    $AF_INET6 = 23\n    $TableBufferSize = 0\n    $null = $iphlpapi::GetExtendedUdpTable([IntPtr]::Zero, [ref]$TableBufferSize, $true, $AF_INET6, $UDP_TABLE_CLASS::UDP_TABLE_OWNER_MODULE, 0)\n    $TableBuffer = [Runtime.InteropServices.Marshal]::AllocHGlobal($TableBufferSize)\n\n    try\n    {\n        $Ret = $iphlpapi::GetExtendedUdpTable($TableBuffer, [ref] $TableBufferSize, $true, $AF_INET6, $UDP_TABLE_CLASS::UDP_TABLE_OWNER_MODULE, 0);\n        if($Ret -eq 50) # ERROR_NOT_SUPPORTED\n        {\n            # IPv6 is not supported\n            return\n        }\n        elseif ($Ret -ne 0)\n        {\n            Write-Error \"Failed to get TCP connection information. GetExtendedTcpTable's return code: $Ret\"\n            return\n        }\n        \n        $OwnerModuleTable  = $TableBuffer -as $MIB_UDP6TABLE_OWNER_MODULE\n        $RowPtr = [IntPtr]($TableBuffer.ToInt64() + [Runtime.InteropServices.Marshal]::OffsetOf($MIB_UDPTABLE_OWNER_MODULE, \"Table\").ToInt64())\n  \n        for($i=0; $i -lt $OwnerModuleTable.NumEntries; $i++)\n        {\n            $UdpRow = $RowPtr -as $MIB_UDP6ROW_OWNER_MODULE\n\n            $LocalAddr = [System.Net.IPAddress]$UdpRow.LocalAddr\n            $PortBytes = [System.BitConverter]::GetBytes($UdpRow.LocalPort)\n            $LocalPort = $PortBytes[0]*256 + $PortBytes[1]\n            $ServiceTag = $UdpRow.OwningModuleInfo[0]\n\n            if($ResolveHostnames) {\n                try {\n                    $RemoteIP = [System.Net.Dns]::GetHostEntry($LocalAddr).HostName\n                }\n                catch {\n\n                }\n            }\n\n            $Output = @{\n                LocalAddress = [string]$LocalAddr\n                LocalPort = $LocalPort\n                Process = (Get-Process -Id $UdpRow.OwningPid -ErrorAction SilentlyContinue).Name\n                ProcessId = $UdpRow.OwningPid\n                Protocol = \"UDP\"\n                Service = [string](Get-ServiceNameFromTag -ProcessId $UdpRow.OwningPid -ServiceTag $ServiceTag)\n            }\n\n            if($ReturnHashtables) {\n                $Output\n            } else {\n                New-Object PSObject -Property $Output \n            }\n\n            # Move to the next row in the UDP table\n            $RowPtr = [IntPtr]($RowPtr.ToInt64() + ([Runtime.InteropServices.Marshal]::SizeOf($UdpRow)))\n        }\n    }\n    catch\n    {\n        Write-Error $_\n    }\n    finally\n    {\n        [Runtime.InteropServices.Marshal]::FreeHGlobal($TableBuffer)\n    }\n}\n#endregion Lee's code...\n#endregion API Abstractions\n\n#Start-AceScript -Uri https://10.182.18.200 -SweepId $args[0] -ScanId ([Guid]::NewGuid()) -Thumbprint 8D1DB3B7B85B6F9E9DE87B291DF66692A10240AE -ScanType RegistryAutoRun\n#Start-AceScript -Uri https://10.182.18.200 -SweepId ([Guid]::NewGuid()) -ScanId ([Guid]::NewGuid()) -Thumbprint 8D1DB3B7B85B6F9E9DE87B291DF66692A10240AE -ScanType All"
  },
  {
    "path": "ACE-Management/PS-ACE/Scripts/ACE_Get-AccessToken.ps1",
    "content": "﻿function Start-AceScript\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $SweepId,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $ScanId,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $RoutingKey,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Thumbprint\n    )\n\n    $HostFQDN = Get-WmiObject Win32_ComputerSystem -Property 'Name','Domain' | ForEach-Object {\"$($_.Name).$($_.Domain)\"}\n    $ResultDate = (Get-Date).ToString(\"yyyyMMddThhmmssmsmsZ\")\n\n    $dataList = New-Object -TypeName System.Collections.Generic.List['string']\n\n    foreach($o in (Get-AccessToken))\n    {\n        $o.Add('ComputerName', $HostFQDN)\n        $o.Add('ScanType', 'AccessToken')\n        $o.Add('SweepId', $SweepId)\n        $o.Add('ScanId', $ScanId)\n        $o.Add('ResultDate', $ResultDate)\n\n        $message = ConvertTo-JsonV2 -InputObject $o\n        $dataList.Add($message)\n    }\n\n    $props = @{\n        ComputerName = $HostFQDN\n        ScanType     = 'AccessToken'\n        RoutingKey   = $RoutingKey\n        ResultDate   = $ResultDate\n        ScanId       = $ScanId\n        Data         = $dataList.ToArray()\n    }\n\n    $body = (ConvertTo-JsonV2 -InputObject $props)\n    \n    #Write-Output $body | ConvertFrom-Json\n    \n    Invoke-AceWebRequest -Thumbprint $Thumbprint -Uri \"$($Uri)/ace/result/$($SweepId)\" -Body $body\n}\n\nfunction ConvertTo-JsonV2 \n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        $InputObject\n    )\n\n    Begin \n    {\n        $null = [System.Reflection.Assembly]::LoadWithPartialName(\"System.Web.Extensions\")\n        $Serializer = New-Object System.Web.Script.Serialization.JavaScriptSerializer\n    }\n\n    Process \n    {\n        try \n        {\n            $Serializer.Serialize($InputObject)\n        } \n        catch \n        {\n            Write-Error $_\n        }    \n    }\n}\n\nfunction Invoke-AceWebRequest\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Thumbprint,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Body\n    )\n\n    [Net.ServicePointManager]::ServerCertificateValidationCallback = {\n        $Thumbprint = $Thumbprint\n        $certificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]$args[1]\n    \n        if ($certificate -eq $null)\n        {\n            $Host.UI.WriteErrorLine(\"Null certificate.\")\n            return $true\n        }\n    \n        if ($certificate.Thumbprint -eq $Thumbprint)\n        {\n            return $true\n        }\n        else\n        {\n            $Host.UI.WriteErrorLine(\"Thumbprint mismatch. Certificate thumbprint $($certificate.Thumbprint)\")\n        }\n    \n        return $false\n    }\n\n    try\n    {\n        Write-Host \"URI: $($Uri)\"\n\n        # Create web request\n        $WebRequest = [Net.WebRequest]::Create($uri)\n        $WebRequest.Method = 'Post'\n        $WebRequest.ContentType = 'application/json'\n        $WebRequest.Headers.Add('X-API-Version:1.0')\n\n        $byteArray = [System.Text.Encoding]::UTF8.GetBytes($Body)\n        $Webrequest.ContentLength = $byteArray.Length\n        \n        $dataStream = $Webrequest.GetRequestStream()            \n        $dataStream.Write($byteArray, 0, $byteArray.Length)\n        $dataStream.Close()\n\n        # Get response stream\n        $ResponseStream = $Webrequest.GetResponse().GetResponseStream()\n    \n        # Create a stream reader and read the stream returning the string value.\n        $StreamReader = New-Object System.IO.StreamReader -ArgumentList $ResponseStream\n        $StreamReader.ReadToEnd()\n    }\n    catch\n    {\n        Write-Error \"Failed: $($_.exception.innerexception.message)\"\n    }\n}\n\nfunction Get-AccessToken\n{\n    param\n    (\n        [Parameter()]\n        [System.Diagnostics.Process[]]\n        $Process\n    )\n\n    begin\n    {\n        <#\n        try\n        {\n            Get-System\n        }\n        catch\n        {\n            Write-Error \"Unable to Impersonate NT AUTHORITY\\SYSTEM token\"\n        }\n        #>\n\n        if(-not ($PSBoundParameters.ContainsKey('Process')))\n        {\n            $Process = Get-Process\n        }\n    }\n\n    process\n    {\n        foreach($proc in $Process)\n        {\n            if($proc.Id -ne 0 -and $proc.Id -ne 4 -and $proc.Id -ne $PID)\n            {\n                $ProcessGuid = [Guid]::NewGuid()\n\n                try\n                {\n                    $hProcess = OpenProcess -ProcessId $proc.Id -DesiredAccess PROCESS_QUERY_LIMITED_INFORMATION\n                }\n                catch\n                {\n                    if($_.Exception.Message -ne \"OpenProcess Error: The parameter is incorrect\")\n                    {\n                        Write-Warning \"Process Handle: $($proc.Id)\"\n                        Write-Warning $_.Exception.Message\n                    }\n                }\n\n                try\n                {\n                    $hToken = OpenProcessToken -ProcessHandle $hProcess -DesiredAccess TOKEN_QUERY\n                }\n                catch\n                {\n                    #Write-Warning \"Process Token Handle: $($proc.Id)\"\n                    #Write-Warning $_.Exception.Message\n                }\n\n                try\n                {\n                    $TokenUser = GetTokenInformation -TokenInformationClass TokenUser -TokenHandle $hToken\n                    $TokenGroup = GetTokenInformation -TokenInformationClass TokenGroups -TokenHandle $hToken\n                    $TokenOwner = GetTokenInformation -TokenInformationClass TokenOwner -TokenHandle $hToken\n                    $TokenIntegrityLevel = GetTokenInformation -TokenInformationClass TokenIntegrityLevel -TokenHandle $hToken\n                    $TokenType = GetTokenInformation -TokenInformationClass TokenType -TokenHandle $hToken\n                    $TokenSessionId = GetTokenInformation -TokenInformationClass TokenSessionId -TokenHandle $hToken\n                    $TokenOrigin = GetTokenInformation -TokenInformationClass TokenOrigin -TokenHandle $hToken\n                    $TokenPrivileges = (GetTokenInformation -TokenInformationClass TokenPrivileges -TokenHandle $hToken | Where-Object {$_.Attributes -like \"*ENABLED*\"} | select -ExpandProperty Privilege) -join \";\"\n                    $TokenElevation = GetTokenInformation -TokenInformationClass TokenElevation -TokenHandle $hToken\n                    $TokenElevationType = GetTokenInformation -TokenInformationClass TokenElevationType -TokenHandle $hToken\n\n                    $props = @{\n                        ProcessGuid = $ProcessGuid\n                        ProcessName = $proc.Name\n                        ProcessId = $proc.Id\n                        ThreadId = 0\n                        UserSid = $TokenUser.Sid.ToString()\n                        UserName = $TokenUser.Name.Value\n                        OwnerSid = $TokenOwner.Sid.ToString()\n                        OwnerName = $TokenOwner.Name.Value\n                        #Groups = $TokenGroup\n                        IntegrityLevel = $TokenIntegrityLevel.ToString()\n                        Type = $TokenType.ToString()\n                        ImpersonationLevel = 'None'\n                        SessionId = $TokenSessionId -as ([Int32])\n                        Origin = $TokenOrigin -as ([Int32])\n                        Privileges = $TokenPrivileges\n                        IsElevated = $TokenElevation -as ([bool])\n                        ElevationType = $TokenElevationType.ToString()\n                    }\n\n                    Write-Output $props\n\n                    CloseHandle -Handle $hProcess\n                    CloseHandle -Handle $hToken\n                }\n                catch\n                {\n                    #Write-Warning \"Process Token Query: $($proc.Id)\"\n                    #Write-Warning $_.Exception.Message\n                }\n\n                foreach($thread in $proc.Threads)\n                {\n                    try\n                    {\n                        $hThread = OpenThread -ThreadId $thread.Id -DesiredAccess THREAD_QUERY_LIMITED_INFORMATION\n\n                        try\n                        {\n                            $hToken = OpenThreadToken -ThreadHandle $hThread -DesiredAccess TOKEN_QUERY\n\n                            $TokenUser = GetTokenInformation -TokenInformationClass TokenUser -TokenHandle $hToken\n                            $TokenGroup = GetTokenInformation -TokenInformationClass TokenGroups -TokenHandle $hToken\n                            $TokenOwner = GetTokenInformation -TokenInformationClass TokenOwner -TokenHandle $hToken\n                            $TokenIntegrityLevel = GetTokenInformation -TokenInformationClass TokenIntegrityLevel -TokenHandle $hToken\n                            $TokenType = GetTokenInformation -TokenInformationClass TokenType -TokenHandle $hToken\n                            if($TokenType -eq 'TokenImpersonation')\n                            {\n                                $TokenImpersonationLevel = GetTokenInformation -TokenInformationClass TokenImpersonationLevel -TokenHandle $hToken\n                            }\n                            else\n                            {\n                                $TokenImpersonationLevel = 'None'\n                            }\n                            $TokenSessionId = GetTokenInformation -TokenInformationClass TokenSessionId -TokenHandle $hToken\n                            $TokenOrigin = GetTokenInformation -TokenInformationClass TokenOrigin -TokenHandle $hToken\n                            $TokenPrivileges = (GetTokenInformation -TokenInformationClass TokenPrivileges -TokenHandle $hToken | Where-Object {$_.Attributes -like \"*ENABLED*\"} | select -ExpandProperty Privilege) -join \";\"\n                            $TokenElevation = GetTokenInformation -TokenInformationClass TokenElevation -TokenHandle $hToken\n                            $TokenElevationType = GetTokenInformation -TokenInformationClass TokenElevationType -TokenHandle $hToken\n                        \n                            $props = @{\n                                ProcessGuid = $ProcessGuid\n                                ProcessName = $proc.Name\n                                ProcessId = $proc.Id\n                                ThreadId = $thread.Id\n                                UserSid = $TokenUser.Sid.ToString()\n                                UserName = $TokenUser.Name.Value\n                                OwnerSid = $TokenOwner.Sid.ToString()\n                                OwnerName = $TokenOwner.Name.Value\n                                #Groups = $TokenGroup\n                                IntegrityLevel = $TokenIntegrityLevel.ToString()\n                                Type = $TokenType.ToString()\n                                ImpersonationLevel = $TokenImpersonationLevel.ToString()\n                                SessionId = $TokenSessionId -as ([Int32])\n                                Origin = $TokenOrigin -as ([Int32])\n                                Privileges = $TokenPrivileges\n                                IsElevated = $TokenElevation -as ([bool])\n                                ElevationType = $TokenElevationType.ToString()\n                            }\n\n                            Write-Output $props    \n\n                            CloseHandle -Handle $hThread\n                            CloseHandle -Handle $hToken\n                        }\n                        catch\n                        {\n                            if($_.Exception.Message -ne 'OpenThreadToken Error: An attempt was made to reference a token that does not exist')\n                            {\n                                #Write-Warning \"Thread Token Handle\"\n                                #Write-Warning $_.Exception.Message\n                            }\n                        }\n                    }\n                    catch\n                    {\n                        #Write-Warning \"Thread Handle: [Proc] $($proc.Id) [THREAD] $($thread.Id)\"\n                        #Write-Warning $_.Exception.Message\n                    }\n                }\n            }\n        }\n    }\n\n    end\n    {\n        RevertToSelf\n    }\n}\n\n#region Helper Functions\nfunction Get-System\n{\n    <#\n    .SYNOPSIS\n\n    Impersonate the NT AUTHORITY\\SYSTEM account's token.\n\n    .DESCRIPTION\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: \n    Required Dependencies: PSReflect, OpenProcessToken (Function), DuplicateToken (Function), ImpersonateLoggedOnUser (Function), CloseHandle (Function)\n    Optional Dependencies: None\n\n    .EXAMPLE\n\n    Get-System\n    #>\n\n    # Get a Process object for the winlogon process\n    # The System.Diagnostics.Process class has a handle property that we can use\n    # We know winlogon will be available and is running as NT AUTHORITY\\SYSTEM\n    $proc = (Get-Process -Name winlogon)[0]\n\n    # Open winlogon's Token with TOKEN_DUPLICATE Acess\n    # This allows us to make a copy of the token with DuplicateToken\n    $hToken = OpenProcessToken -ProcessHandle $proc.Handle -DesiredAccess $TOKEN_ACCESS::TOKEN_DUPLICATE\n    \n    # Make a copy of the NT AUTHORITY\\SYSTEM Token\n    $hDupToken = DuplicateToken -TokenHandle $hToken\n    \n    # Apply our Duplicated Token to our Thread\n    ImpersonateLoggedOnUser -TokenHandle $hDupToken\n    \n    # Clean up the handles we created\n    CloseHandle -Handle $hToken\n    CloseHandle -Handle $hDupToken\n\n    if(-not [System.Security.Principal.WindowsIdentity]::GetCurrent().Name -eq 'NT AUTHORITY\\SYSTEM')\n    {\n        throw \"Unable to Impersonate System Token\"\n    }\n}\n#endregion Helper Functions\n\n#region PSReflect\n\n#Requires -Version 2\n\nfunction New-InMemoryModule\n{\n<#\n.SYNOPSIS\n\nCreates an in-memory assembly and module\n\nAuthor: Matthew Graeber (@mattifestation)\nLicense: BSD 3-Clause\nRequired Dependencies: None\nOptional Dependencies: None\n \n.DESCRIPTION\n\nWhen defining custom enums, structs, and unmanaged functions, it is\nnecessary to associate to an assembly module. This helper function\ncreates an in-memory module that can be passed to the 'enum',\n'struct', and Add-Win32Type functions.\n\n.PARAMETER ModuleName\n\nSpecifies the desired name for the in-memory assembly and module. If\nModuleName is not provided, it will default to a GUID.\n\n.EXAMPLE\n\n$Module = New-InMemoryModule -ModuleName Win32\n#>\n\n    Param\n    (\n        [Parameter(Position = 0)]\n        [ValidateNotNullOrEmpty()]\n        [String]\n        $ModuleName = [Guid]::NewGuid().ToString()\n    )\n\n    $AppDomain = [Reflection.Assembly].Assembly.GetType('System.AppDomain').GetProperty('CurrentDomain').GetValue($null, @())\n    $LoadedAssemblies = $AppDomain.GetAssemblies()\n\n    foreach ($Assembly in $LoadedAssemblies) {\n        if ($Assembly.FullName -and ($Assembly.FullName.Split(',')[0] -eq $ModuleName)) {\n            return $Assembly\n        }\n    }\n\n    $DynAssembly = New-Object Reflection.AssemblyName($ModuleName)\n    $Domain = $AppDomain\n    $AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, 'Run')\n    $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule($ModuleName, $False)\n\n    return $ModuleBuilder\n}\n\n\n# A helper function used to reduce typing while defining function\n# prototypes for Add-Win32Type.\nfunction func\n{\n    Param\n    (\n        [Parameter(Position = 0, Mandatory = $True)]\n        [String]\n        $DllName,\n\n        [Parameter(Position = 1, Mandatory = $True)]\n        [string]\n        $FunctionName,\n\n        [Parameter(Position = 2, Mandatory = $True)]\n        [Type]\n        $ReturnType,\n\n        [Parameter(Position = 3)]\n        [Type[]]\n        $ParameterTypes,\n\n        [Parameter(Position = 4)]\n        [Runtime.InteropServices.CallingConvention]\n        $NativeCallingConvention,\n\n        [Parameter(Position = 5)]\n        [Runtime.InteropServices.CharSet]\n        $Charset,\n\n        [String]\n        $EntryPoint,\n\n        [Switch]\n        $SetLastError\n    )\n\n    $Properties = @{\n        DllName = $DllName\n        FunctionName = $FunctionName\n        ReturnType = $ReturnType\n    }\n\n    if ($ParameterTypes) { $Properties['ParameterTypes'] = $ParameterTypes }\n    if ($NativeCallingConvention) { $Properties['NativeCallingConvention'] = $NativeCallingConvention }\n    if ($Charset) { $Properties['Charset'] = $Charset }\n    if ($SetLastError) { $Properties['SetLastError'] = $SetLastError }\n    if ($EntryPoint) { $Properties['EntryPoint'] = $EntryPoint }\n\n    New-Object PSObject -Property $Properties\n}\n\n\nfunction Add-Win32Type\n{\n<#\n.SYNOPSIS\n\nCreates a .NET type for an unmanaged Win32 function.\n\nAuthor: Matthew Graeber (@mattifestation)\nLicense: BSD 3-Clause\nRequired Dependencies: None\nOptional Dependencies: func\n \n.DESCRIPTION\n\nAdd-Win32Type enables you to easily interact with unmanaged (i.e.\nWin32 unmanaged) functions in PowerShell. After providing\nAdd-Win32Type with a function signature, a .NET type is created\nusing reflection (i.e. csc.exe is never called like with Add-Type).\n\nThe 'func' helper function can be used to reduce typing when defining\nmultiple function definitions.\n\n.PARAMETER DllName\n\nThe name of the DLL.\n\n.PARAMETER FunctionName\n\nThe name of the target function.\n\n.PARAMETER EntryPoint\n\nThe DLL export function name. This argument should be specified if the\nspecified function name is different than the name of the exported\nfunction.\n\n.PARAMETER ReturnType\n\nThe return type of the function.\n\n.PARAMETER ParameterTypes\n\nThe function parameters.\n\n.PARAMETER NativeCallingConvention\n\nSpecifies the native calling convention of the function. Defaults to\nstdcall.\n\n.PARAMETER Charset\n\nIf you need to explicitly call an 'A' or 'W' Win32 function, you can\nspecify the character set.\n\n.PARAMETER SetLastError\n\nIndicates whether the callee calls the SetLastError Win32 API\nfunction before returning from the attributed method.\n\n.PARAMETER Module\n\nThe in-memory module that will host the functions. Use\nNew-InMemoryModule to define an in-memory module.\n\n.PARAMETER Namespace\n\nAn optional namespace to prepend to the type. Add-Win32Type defaults\nto a namespace consisting only of the name of the DLL.\n\n.EXAMPLE\n\n$Mod = New-InMemoryModule -ModuleName Win32\n\n$FunctionDefinitions = @(\n  (func kernel32 GetProcAddress ([IntPtr]) @([IntPtr], [String]) -Charset Ansi -SetLastError),\n  (func kernel32 GetModuleHandle ([Intptr]) @([String]) -SetLastError),\n  (func ntdll RtlGetCurrentPeb ([IntPtr]) @())\n)\n\n$Types = $FunctionDefinitions | Add-Win32Type -Module $Mod -Namespace 'Win32'\n$Kernel32 = $Types['kernel32']\n$Ntdll = $Types['ntdll']\n$Ntdll::RtlGetCurrentPeb()\n$ntdllbase = $Kernel32::GetModuleHandle('ntdll')\n$Kernel32::GetProcAddress($ntdllbase, 'RtlGetCurrentPeb')\n\n.NOTES\n\nInspired by Lee Holmes' Invoke-WindowsApi http://poshcode.org/2189\n\nWhen defining multiple function prototypes, it is ideal to provide\nAdd-Win32Type with an array of function signatures. That way, they\nare all incorporated into the same in-memory module.\n#>\n\n    [OutputType([Hashtable])]\n    Param(\n        [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)]\n        [String]\n        $DllName,\n\n        [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)]\n        [String]\n        $FunctionName,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [String]\n        $EntryPoint,\n\n        [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)]\n        [Type]\n        $ReturnType,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [Type[]]\n        $ParameterTypes,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [Runtime.InteropServices.CallingConvention]\n        $NativeCallingConvention = [Runtime.InteropServices.CallingConvention]::StdCall,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [Runtime.InteropServices.CharSet]\n        $Charset = [Runtime.InteropServices.CharSet]::Auto,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [Switch]\n        $SetLastError,\n\n        [Parameter(Mandatory = $True)]\n        [ValidateScript({($_ -is [Reflection.Emit.ModuleBuilder]) -or ($_ -is [Reflection.Assembly])})]\n        $Module,\n\n        [ValidateNotNull()]\n        [String]\n        $Namespace = ''\n    )\n\n    BEGIN\n    {\n        $TypeHash = @{}\n    }\n\n    PROCESS\n    {\n        if ($Module -is [Reflection.Assembly])\n        {\n            if ($Namespace)\n            {\n                $TypeHash[$DllName] = $Module.GetType(\"$Namespace.$DllName\")\n            }\n            else\n            {\n                $TypeHash[$DllName] = $Module.GetType($DllName)\n            }\n        }\n        else\n        {\n            # Define one type for each DLL\n            if (!$TypeHash.ContainsKey($DllName))\n            {\n                if ($Namespace)\n                {\n                    $TypeHash[$DllName] = $Module.DefineType(\"$Namespace.$DllName\", 'Public,BeforeFieldInit')\n                }\n                else\n                {\n                    $TypeHash[$DllName] = $Module.DefineType($DllName, 'Public,BeforeFieldInit')\n                }\n            }\n\n            $Method = $TypeHash[$DllName].DefineMethod(\n                $FunctionName,\n                'Public,Static,PinvokeImpl',\n                $ReturnType,\n                $ParameterTypes)\n\n            # Make each ByRef parameter an Out parameter\n            $i = 1\n            foreach($Parameter in $ParameterTypes)\n            {\n                if ($Parameter.IsByRef)\n                {\n                    [void] $Method.DefineParameter($i, 'Out', $null)\n                }\n\n                $i++\n            }\n\n            $DllImport = [Runtime.InteropServices.DllImportAttribute]\n            $SetLastErrorField = $DllImport.GetField('SetLastError')\n            $CallingConventionField = $DllImport.GetField('CallingConvention')\n            $CharsetField = $DllImport.GetField('CharSet')\n            $EntryPointField = $DllImport.GetField('EntryPoint')\n            if ($SetLastError) { $SLEValue = $True } else { $SLEValue = $False }\n\n            if ($PSBoundParameters['EntryPoint']) { $ExportedFuncName = $EntryPoint } else { $ExportedFuncName = $FunctionName }\n\n            # Equivalent to C# version of [DllImport(DllName)]\n            $Constructor = [Runtime.InteropServices.DllImportAttribute].GetConstructor([String])\n            $DllImportAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($Constructor,\n                $DllName, [Reflection.PropertyInfo[]] @(), [Object[]] @(),\n                [Reflection.FieldInfo[]] @($SetLastErrorField,\n                                           $CallingConventionField,\n                                           $CharsetField,\n                                           $EntryPointField),\n                [Object[]] @($SLEValue,\n                             ([Runtime.InteropServices.CallingConvention] $NativeCallingConvention),\n                             ([Runtime.InteropServices.CharSet] $Charset),\n                             $ExportedFuncName))\n\n            $Method.SetCustomAttribute($DllImportAttribute)\n        }\n    }\n\n    END\n    {\n        if ($Module -is [Reflection.Assembly])\n        {\n            return $TypeHash\n        }\n\n        $ReturnTypes = @{}\n\n        foreach ($Key in $TypeHash.Keys)\n        {\n            $Type = $TypeHash[$Key].CreateType()\n            \n            $ReturnTypes[$Key] = $Type\n        }\n\n        return $ReturnTypes\n    }\n}\n\n\nfunction psenum\n{\n<#\n.SYNOPSIS\n\nCreates an in-memory enumeration for use in your PowerShell session.\n\nAuthor: Matthew Graeber (@mattifestation)\nLicense: BSD 3-Clause\nRequired Dependencies: None\nOptional Dependencies: None\n \n.DESCRIPTION\n\nThe 'psenum' function facilitates the creation of enums entirely in\nmemory using as close to a \"C style\" as PowerShell will allow.\n\n.PARAMETER Module\n\nThe in-memory module that will host the enum. Use\nNew-InMemoryModule to define an in-memory module.\n\n.PARAMETER FullName\n\nThe fully-qualified name of the enum.\n\n.PARAMETER Type\n\nThe type of each enum element.\n\n.PARAMETER EnumElements\n\nA hashtable of enum elements.\n\n.PARAMETER Bitfield\n\nSpecifies that the enum should be treated as a bitfield.\n\n.EXAMPLE\n\n$Mod = New-InMemoryModule -ModuleName Win32\n\n$ImageSubsystem = psenum $Mod PE.IMAGE_SUBSYSTEM UInt16 @{\n    UNKNOWN =                  0\n    NATIVE =                   1 # Image doesn't require a subsystem.\n    WINDOWS_GUI =              2 # Image runs in the Windows GUI subsystem.\n    WINDOWS_CUI =              3 # Image runs in the Windows character subsystem.\n    OS2_CUI =                  5 # Image runs in the OS/2 character subsystem.\n    POSIX_CUI =                7 # Image runs in the Posix character subsystem.\n    NATIVE_WINDOWS =           8 # Image is a native Win9x driver.\n    WINDOWS_CE_GUI =           9 # Image runs in the Windows CE subsystem.\n    EFI_APPLICATION =          10\n    EFI_BOOT_SERVICE_DRIVER =  11\n    EFI_RUNTIME_DRIVER =       12\n    EFI_ROM =                  13\n    XBOX =                     14\n    WINDOWS_BOOT_APPLICATION = 16\n}\n\n.NOTES\n\nPowerShell purists may disagree with the naming of this function but\nagain, this was developed in such a way so as to emulate a \"C style\"\ndefinition as closely as possible. Sorry, I'm not going to name it\nNew-Enum. :P\n#>\n\n    [OutputType([Type])]\n    Param\n    (\n        [Parameter(Position = 0, Mandatory = $True)]\n        [ValidateScript({($_ -is [Reflection.Emit.ModuleBuilder]) -or ($_ -is [Reflection.Assembly])})]\n        $Module,\n\n        [Parameter(Position = 1, Mandatory = $True)]\n        [ValidateNotNullOrEmpty()]\n        [String]\n        $FullName,\n\n        [Parameter(Position = 2, Mandatory = $True)]\n        [Type]\n        $Type,\n\n        [Parameter(Position = 3, Mandatory = $True)]\n        [ValidateNotNullOrEmpty()]\n        [Hashtable]\n        $EnumElements,\n\n        [Switch]\n        $Bitfield\n    )\n\n    if ($Module -is [Reflection.Assembly])\n    {\n        return ($Module.GetType($FullName))\n    }\n\n    $EnumType = $Type -as [Type]\n\n    $EnumBuilder = $Module.DefineEnum($FullName, 'Public', $EnumType)\n\n    if ($Bitfield)\n    {\n        $FlagsConstructor = [FlagsAttribute].GetConstructor(@())\n        $FlagsCustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($FlagsConstructor, @())\n        $EnumBuilder.SetCustomAttribute($FlagsCustomAttribute)\n    }\n\n    foreach ($Key in $EnumElements.Keys)\n    {\n        # Apply the specified enum type to each element\n        $null = $EnumBuilder.DefineLiteral($Key, $EnumElements[$Key] -as $EnumType)\n    }\n\n    $EnumBuilder.CreateType()\n}\n\n\n# A helper function used to reduce typing while defining struct\n# fields.\nfunction field\n{\n    Param\n    (\n        [Parameter(Position = 0, Mandatory = $True)]\n        [UInt16]\n        $Position,\n        \n        [Parameter(Position = 1, Mandatory = $True)]\n        [Type]\n        $Type,\n        \n        [Parameter(Position = 2)]\n        [UInt16]\n        $Offset,\n        \n        [Object[]]\n        $MarshalAs\n    )\n\n    @{\n        Position = $Position\n        Type = $Type -as [Type]\n        Offset = $Offset\n        MarshalAs = $MarshalAs\n    }\n}\n\n\nfunction struct\n{\n<#\n.SYNOPSIS\n\nCreates an in-memory struct for use in your PowerShell session.\n\nAuthor: Matthew Graeber (@mattifestation)\nLicense: BSD 3-Clause\nRequired Dependencies: None\nOptional Dependencies: field\n \n.DESCRIPTION\n\nThe 'struct' function facilitates the creation of structs entirely in\nmemory using as close to a \"C style\" as PowerShell will allow. Struct\nfields are specified using a hashtable where each field of the struct\nis comprosed of the order in which it should be defined, its .NET\ntype, and optionally, its offset and special marshaling attributes.\n\nOne of the features of 'struct' is that after your struct is defined,\nit will come with a built-in GetSize method as well as an explicit\nconverter so that you can easily cast an IntPtr to the struct without\nrelying upon calling SizeOf and/or PtrToStructure in the Marshal\nclass.\n\n.PARAMETER Module\n\nThe in-memory module that will host the struct. Use\nNew-InMemoryModule to define an in-memory module.\n\n.PARAMETER FullName\n\nThe fully-qualified name of the struct.\n\n.PARAMETER StructFields\n\nA hashtable of fields. Use the 'field' helper function to ease\ndefining each field.\n\n.PARAMETER PackingSize\n\nSpecifies the memory alignment of fields.\n\n.PARAMETER ExplicitLayout\n\nIndicates that an explicit offset for each field will be specified.\n\n.PARAMETER CharSet\n\nDictates which character set marshaled strings should use.\n\n.EXAMPLE\n\n$Mod = New-InMemoryModule -ModuleName Win32\n\n$ImageDosSignature = psenum $Mod PE.IMAGE_DOS_SIGNATURE UInt16 @{\n    DOS_SIGNATURE =    0x5A4D\n    OS2_SIGNATURE =    0x454E\n    OS2_SIGNATURE_LE = 0x454C\n    VXD_SIGNATURE =    0x454C\n}\n\n$ImageDosHeader = struct $Mod PE.IMAGE_DOS_HEADER @{\n    e_magic =    field 0 $ImageDosSignature\n    e_cblp =     field 1 UInt16\n    e_cp =       field 2 UInt16\n    e_crlc =     field 3 UInt16\n    e_cparhdr =  field 4 UInt16\n    e_minalloc = field 5 UInt16\n    e_maxalloc = field 6 UInt16\n    e_ss =       field 7 UInt16\n    e_sp =       field 8 UInt16\n    e_csum =     field 9 UInt16\n    e_ip =       field 10 UInt16\n    e_cs =       field 11 UInt16\n    e_lfarlc =   field 12 UInt16\n    e_ovno =     field 13 UInt16\n    e_res =      field 14 UInt16[] -MarshalAs @('ByValArray', 4)\n    e_oemid =    field 15 UInt16\n    e_oeminfo =  field 16 UInt16\n    e_res2 =     field 17 UInt16[] -MarshalAs @('ByValArray', 10)\n    e_lfanew =   field 18 Int32\n}\n\n# Example of using an explicit layout in order to create a union.\n$TestUnion = struct $Mod TestUnion @{\n    field1 = field 0 UInt32 0\n    field2 = field 1 IntPtr 0\n} -ExplicitLayout\n\n.NOTES\n\nPowerShell purists may disagree with the naming of this function but\nagain, this was developed in such a way so as to emulate a \"C style\"\ndefinition as closely as possible. Sorry, I'm not going to name it\nNew-Struct. :P\n#>\n\n    [OutputType([Type])]\n    Param\n    (\n        [Parameter(Position = 1, Mandatory = $True)]\n        [ValidateScript({($_ -is [Reflection.Emit.ModuleBuilder]) -or ($_ -is [Reflection.Assembly])})]\n        $Module,\n\n        [Parameter(Position = 2, Mandatory = $True)]\n        [ValidateNotNullOrEmpty()]\n        [String]\n        $FullName,\n\n        [Parameter(Position = 3, Mandatory = $True)]\n        [ValidateNotNullOrEmpty()]\n        [Hashtable]\n        $StructFields,\n\n        [Reflection.Emit.PackingSize]\n        $PackingSize = [Reflection.Emit.PackingSize]::Unspecified,\n\n        [Switch]\n        $ExplicitLayout,\n\n        [System.Runtime.InteropServices.CharSet]\n        $CharSet = [System.Runtime.InteropServices.CharSet]::Ansi\n    )\n\n    if ($Module -is [Reflection.Assembly])\n    {\n        return ($Module.GetType($FullName))\n    }\n\n    [Reflection.TypeAttributes] $StructAttributes = 'Class,\n        Public,\n        Sealed,\n        BeforeFieldInit'\n\n    if ($ExplicitLayout)\n    {\n        $StructAttributes = $StructAttributes -bor [Reflection.TypeAttributes]::ExplicitLayout\n    }\n    else\n    {\n        $StructAttributes = $StructAttributes -bor [Reflection.TypeAttributes]::SequentialLayout\n    }\n\n    switch($CharSet)\n    {\n        Ansi\n        {\n            $StructAttributes = $StructAttributes -bor [Reflection.TypeAttributes]::AnsiClass\n        }\n        Auto\n        {\n            $StructAttributes = $StructAttributes -bor [Reflection.TypeAttributes]::AutoClass\n        }\n        Unicode\n        {\n            $StructAttributes = $StructAttributes -bor [Reflection.TypeAttributes]::UnicodeClass\n        }\n    }\n\n    $StructBuilder = $Module.DefineType($FullName, $StructAttributes, [ValueType], $PackingSize)\n    $ConstructorInfo = [Runtime.InteropServices.MarshalAsAttribute].GetConstructors()[0]\n    $SizeConst = @([Runtime.InteropServices.MarshalAsAttribute].GetField('SizeConst'))\n\n    $Fields = New-Object Hashtable[]($StructFields.Count)\n\n    # Sort each field according to the orders specified\n    # Unfortunately, PSv2 doesn't have the luxury of the\n    # hashtable [Ordered] accelerator.\n    foreach ($Field in $StructFields.Keys)\n    {\n        $Index = $StructFields[$Field]['Position']\n        $Fields[$Index] = @{FieldName = $Field; Properties = $StructFields[$Field]}\n    }\n\n    foreach ($Field in $Fields)\n    {\n        $FieldName = $Field['FieldName']\n        $FieldProp = $Field['Properties']\n\n        $Offset = $FieldProp['Offset']\n        $Type = $FieldProp['Type']\n        $MarshalAs = $FieldProp['MarshalAs']\n\n        $NewField = $StructBuilder.DefineField($FieldName, $Type, 'Public')\n\n        if ($MarshalAs)\n        {\n            $UnmanagedType = $MarshalAs[0] -as ([Runtime.InteropServices.UnmanagedType])\n            if ($MarshalAs[1])\n            {\n                $Size = $MarshalAs[1]\n                $AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($ConstructorInfo,\n                    $UnmanagedType, $SizeConst, @($Size))\n            }\n            else\n            {\n                $AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($ConstructorInfo, [Object[]] @($UnmanagedType))\n            }\n            \n            $NewField.SetCustomAttribute($AttribBuilder)\n        }\n\n        if ($ExplicitLayout) { $NewField.SetOffset($Offset) }\n    }\n\n    # Make the struct aware of its own size.\n    # No more having to call [Runtime.InteropServices.Marshal]::SizeOf!\n    $SizeMethod = $StructBuilder.DefineMethod('GetSize',\n        'Public, Static',\n        [Int],\n        [Type[]] @())\n    $ILGenerator = $SizeMethod.GetILGenerator()\n    # Thanks for the help, Jason Shirk!\n    $ILGenerator.Emit([Reflection.Emit.OpCodes]::Ldtoken, $StructBuilder)\n    $ILGenerator.Emit([Reflection.Emit.OpCodes]::Call,\n        [Type].GetMethod('GetTypeFromHandle'))\n    $ILGenerator.Emit([Reflection.Emit.OpCodes]::Call,\n        [Runtime.InteropServices.Marshal].GetMethod('SizeOf', [Type[]] @([Type])))\n    $ILGenerator.Emit([Reflection.Emit.OpCodes]::Ret)\n\n    # Allow for explicit casting from an IntPtr\n    # No more having to call [Runtime.InteropServices.Marshal]::PtrToStructure!\n    $ImplicitConverter = $StructBuilder.DefineMethod('op_Implicit',\n        'PrivateScope, Public, Static, HideBySig, SpecialName',\n        $StructBuilder,\n        [Type[]] @([IntPtr]))\n    $ILGenerator2 = $ImplicitConverter.GetILGenerator()\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Nop)\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ldarg_0)\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ldtoken, $StructBuilder)\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Call,\n        [Type].GetMethod('GetTypeFromHandle'))\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Call,\n        [Runtime.InteropServices.Marshal].GetMethod('PtrToStructure', [Type[]] @([IntPtr], [Type])))\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Unbox_Any, $StructBuilder)\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ret)\n\n    $StructBuilder.CreateType()\n}\n\n#endregion PSReflect\n\n$Module = New-InMemoryModule -ModuleName AccessToken\n\n#region Enums\n$LuidAttributes = psenum $Module LuidAttributes UInt32 @{\n    DISABLED                        = 0x00000000\n    SE_PRIVILEGE_ENABLED_BY_DEFAULT = 0x00000001\n    SE_PRIVILEGE_ENABLED            = 0x00000002\n    SE_PRIVILEGE_REMOVED            = 0x00000004\n    SE_PRIVILEGE_USED_FOR_ACCESS    = 2147483648\n} -Bitfield\n\n$PROCESS_ACCESS = psenum $Module PROCESS_ACCESS UInt32 @{\n    PROCESS_TERMINATE                 = 0x00000001\n    PROCESS_CREATE_THREAD             = 0x00000002\n    PROCESS_VM_OPERATION              = 0x00000008\n    PROCESS_VM_READ                   = 0x00000010\n    PROCESS_VM_WRITE                  = 0x00000020\n    PROCESS_DUP_HANDLE                = 0x00000040\n    PROCESS_CREATE_PROCESS            = 0x00000080\n    PROCESS_SET_QUOTA                 = 0x00000100\n    PROCESS_SET_INFORMATION           = 0x00000200\n    PROCESS_QUERY_INFORMATION         = 0x00000400\n    PROCESS_SUSPEND_RESUME            = 0x00000800\n    PROCESS_QUERY_LIMITED_INFORMATION = 0x00001000\n    DELETE                            = 0x00010000\n    READ_CONTROL                      = 0x00020000\n    WRITE_DAC                         = 0x00040000\n    WRITE_OWNER                       = 0x00080000\n    SYNCHRONIZE                       = 0x00100000\n    PROCESS_ALL_ACCESS                = 0x001f1ffb\n} -Bitfield\n\n$SE_GROUP = psenum $Module SE_GROUP UInt32 @{\n    DISABLED           = 0x00000000\n    MANDATORY          = 0x00000001\n    ENABLED_BY_DEFAULT = 0x00000002\n    ENABLED            = 0x00000004\n    OWNER              = 0x00000008\n    USE_FOR_DENY_ONLY  = 0x00000010\n    INTEGRITY          = 0x00000020\n    INTEGRITY_ENABLED  = 0x00000040\n    RESOURCE           = 0x20000000\n    LOGON_ID           = 3221225472\n} -Bitfield\n\n$SE_PRIVILEGE = psenum $Module SE_PRIVILEGE UInt32 @{\n    DISABLED           = 0x00000000\n    ENABLED_BY_DEFAULT = 0x00000001\n    ENABLED            = 0x00000002\n    REMOVED            = 0x00000004\n    USED_FOR_ACCESS    = 2147483648\n} -Bitfield\n\n$SECURITY_IMPERSONATION_LEVEL = psenum $Module SECURITY_IMPERSONATION_LEVEL UInt32 @{\n    SecurityAnonymous      = 0\n    SecurityIdentification = 1\n    SecurityImpersonation  = 2\n    SecurityDelegation     = 3\n}\n\n$SecurityEntity = psenum $Module SecurityEntity UInt32 @{\n    SeCreateTokenPrivilege          = 1\n    SeAssignPrimaryTokenPrivilege   = 2\n    SeLockMemoryPrivilege           = 3\n    SeIncreaseQuotaPrivilege        = 4\n    SeUnsolicitedInputPrivilege     = 5\n    SeMachineAccountPrivilege       = 6\n    SeTcbPrivilege                  = 7\n    SeSecurityPrivilege             = 8\n    SeTakeOwnershipPrivilege        = 9\n    SeLoadDriverPrivilege           = 10\n    SeSystemProfilePrivilege        = 11\n    SeSystemtimePrivilege           = 12\n    SeProfileSingleProcessPrivilege = 13\n    SeIncreaseBasePriorityPrivilege = 14\n    SeCreatePagefilePrivilege       = 15\n    SeCreatePermanentPrivilege      = 16\n    SeBackupPrivilege               = 17\n    SeRestorePrivilege              = 18\n    SeShutdownPrivilege             = 19\n    SeDebugPrivilege                = 20\n    SeAuditPrivilege                = 21\n    SeSystemEnvironmentPrivilege    = 22\n    SeChangeNotifyPrivilege         = 23\n    SeRemoteShutdownPrivilege       = 24\n    SeUndockPrivilege               = 25\n    SeSyncAgentPrivilege            = 26\n    SeEnableDelegationPrivilege     = 27\n    SeManageVolumePrivilege         = 28\n    SeImpersonatePrivilege          = 29\n    SeCreateGlobalPrivilege         = 30\n    SeTrustedCredManAccessPrivilege = 31\n    SeRelabelPrivilege              = 32\n    SeIncreaseWorkingSetPrivilege   = 33\n    SeTimeZonePrivilege             = 34\n    SeCreateSymbolicLinkPrivilege   = 35\n}\n\n$THREAD_ACCESS = psenum $Module THREAD_ACCESS UInt32 @{\n    THREAD_TERMINATE                 = 0x00000001\n    THREAD_SUSPEND_RESUME            = 0x00000002\n    THREAD_GET_CONTEXT               = 0x00000008\n    THREAD_SET_CONTEXT               = 0x00000010\n    THREAD_SET_INFORMATION           = 0x00000020\n    THREAD_QUERY_INFORMATION         = 0x00000040\n    THREAD_SET_THREAD_TOKEN          = 0x00000080\n    THREAD_IMPERSONATE               = 0x00000100\n    THREAD_DIRECT_IMPERSONATION      = 0x00000200\n    THREAD_SET_LIMITED_INFORMATION   = 0x00000400\n    THREAD_QUERY_LIMITED_INFORMATION = 0x00000800\n    DELETE                           = 0x00010000\n    READ_CONTROL                     = 0x00020000\n    WRITE_DAC                        = 0x00040000\n    WRITE_OWNER                      = 0x00080000\n    SYNCHRONIZE                      = 0x00100000\n    THREAD_ALL_ACCESS                = 0x001f0ffb\n} -Bitfield\n\n$TOKEN_ACCESS = psenum $Module TOKEN_ACCESS UInt32 @{\n    TOKEN_DUPLICATE          = 0x00000002\n    TOKEN_IMPERSONATE        = 0x00000004\n    TOKEN_QUERY              = 0x00000008\n    TOKEN_QUERY_SOURCE       = 0x00000010\n    TOKEN_ADJUST_PRIVILEGES  = 0x00000020\n    TOKEN_ADJUST_GROUPS      = 0x00000040\n    TOKEN_ADJUST_DEFAULT     = 0x00000080\n    TOKEN_ADJUST_SESSIONID   = 0x00000100\n    DELETE                   = 0x00010000\n    READ_CONTROL             = 0x00020000\n    WRITE_DAC                = 0x00040000\n    WRITE_OWNER              = 0x00080000\n    SYNCHRONIZE              = 0x00100000\n    STANDARD_RIGHTS_REQUIRED = 0x000F0000\n    TOKEN_ALL_ACCESS         = 0x001f01ff\n} -Bitfield\n\n$TOKEN_ELEVATION_TYPE = psenum $Module TOKEN_ELEVATION_TYPE UInt32 @{ \n    TokenElevationTypeDefault = 1\n    TokenElevationTypeFull    = 2\n    TokenElevationTypeLimited = 3\n}\n\n$TOKEN_INFORMATION_CLASS = psenum $Module TOKEN_INFORMATION_CLASS UInt16 @{ \n    TokenUser                            = 1\n    TokenGroups                          = 2\n    TokenPrivileges                      = 3\n    TokenOwner                           = 4\n    TokenPrimaryGroup                    = 5\n    TokenDefaultDacl                     = 6\n    TokenSource                          = 7\n    TokenType                            = 8\n    TokenImpersonationLevel              = 9\n    TokenStatistics                      = 10\n    TokenRestrictedSids                  = 11\n    TokenSessionId                       = 12\n    TokenGroupsAndPrivileges             = 13\n    TokenSessionReference                = 14\n    TokenSandBoxInert                    = 15\n    TokenAuditPolicy                     = 16\n    TokenOrigin                          = 17\n    TokenElevationType                   = 18\n    TokenLinkedToken                     = 19\n    TokenElevation                       = 20\n    TokenHasRestrictions                 = 21\n    TokenAccessInformation               = 22\n    TokenVirtualizationAllowed           = 23\n    TokenVirtualizationEnabled           = 24\n    TokenIntegrityLevel                  = 25\n    TokenUIAccess                        = 26\n    TokenMandatoryPolicy                 = 27\n    TokenLogonSid                        = 28\n    TokenIsAppContainer                  = 29\n    TokenCapabilities                    = 30\n    TokenAppContainerSid                 = 31\n    TokenAppContainerNumber              = 32\n    TokenUserClaimAttributes             = 33\n    TokenDeviceClaimAttributes           = 34\n    TokenRestrictedUserClaimAttributes   = 35\n    TokenRestrictedDeviceClaimAttributes = 36\n    TokenDeviceGroups                    = 37\n    TokenRestrictedDeviceGroups          = 38\n    TokenSecurityAttributes              = 39\n    TokenIsRestricted                    = 40\n    MaxTokenInfoClass                    = 41\n}\n\n$TOKENMANDATORYPOLICY = psenum $Module TOKENMANDATORYPOLICY UInt32 @{\n    OFF                    = 0x0\n    NO_WRITE_UP            = 0x1\n    POLICY_NEW_PROCESS_MIN = 0x2\n    POLICY_VALID_MASK      = 0x3\n}\n\n$TOKEN_TYPE = psenum $Module TOKEN_TYPE UInt32 @{\n    TokenPrimary       = 1\n    TokenImpersonation = 2\n}\n#endregion Enums\n\n#region Structs\n$ACL = struct $Module ACL @{\n    AclRevision = field 0 Byte\n    Sbz1        = field 1 Byte\n    AclSize     = field 2 UInt16\n    AceCount    = field 3 UInt16\n    Sbz2        = field 4 UInt16\n}\n\n$LUID = struct $Module LUID @{\n    LowPart  = field 0 $SecurityEntity\n    HighPart = field 1 Int32\n}\n\n$LUID_AND_ATTRIBUTES = struct $Module LUID_AND_ATTRIBUTES @{\n    Luid       = field 0 $LUID\n    Attributes = field 1 $SE_PRIVILEGE\n}\n\n$SID_AND_ATTRIBUTES = struct $Module SID_AND_ATTRIBUTES @{\n    Sid        = field 0 IntPtr\n    Attributes = field 1 $SE_GROUP\n} -PackingSize Size8\n\n$TOKEN_APPCONTAINER_INFORMATION = struct $Module TOKEN_APPCONSTAINER_INFORMATION @{\n    TokenAppContainer = field 0 IntPtr\n}\n\n$TOKEN_DEFAULT_DACL = struct $Module TOKEN_DEFAULT_DACL @{\n    DefaultDacl = field 0 $ACL\n}\n\n$TOKEN_ELEVATION = struct $Module TOKEN_ELEVATION @{\n    TokenIsElevated = field 0 UInt32\n}\n\n$TOKEN_GROUPS = struct $Module TOKEN_GROUPS @{\n    GroupCount = field 0 UInt32\n    Groups     = field 1 $SID_AND_ATTRIBUTES.MakeArrayType() -MarshalAs ('ByValArray', 50)\n}\n\n$TOKEN_GROUPS_AND_PRIVILEGES = struct $Module TOKEN_GROUPS_AND_PRIVILEGES @{\n    SidCount            = field 0 UInt32\n    SidLength           = field 1 UInt32\n    Sids                = field 2 IntPtr\n    RestrictedSidCount  = field 3 UInt32\n    RestrictedSidLength = field 4 UInt32\n    RestrictedSids      = field 5 IntPtr\n    PrivilegeCount      = field 6 UInt32\n    PrivilegeLength     = field 7 UInt32\n    Privileges          = field 8 IntPtr\n    AuthenticationId    = field 9 $LUID\n}\n\n$TOKEN_LINKED_TOKEN = struct $Module TOKEN_LINKED_TOKEN @{\n    LinkedToken = field 0 IntPtr\n}\n\n$TOKEN_MANDATORY_LABEL = struct $Module TOKEN_MANDATORY_LABEL @{\n    Label = field 0 $SID_AND_ATTRIBUTES\n}\n\n$TOKEN_MANDATORY_POLICY = struct $Module TOKEN_MANDATORY_POLICY @{\n    Policy = field 0 $TOKENMANDATORYPOLICY\n}\n\n$TOKEN_OWNER = struct $Module TOKEN_OWNER @{\n    Owner = field 0 IntPtr\n}\n\n$TOKEN_PRIVILEGES = struct $Module TOKEN_PRIVILEGES @{\n    PrivilegeCount = field 0 UInt32\n    Privileges     = field 1  $LUID_AND_ATTRIBUTES.MakeArrayType() -MarshalAs @('ByValArray', 50)\n}\n\n$TOKEN_SOURCE = struct $Module TOKEN_SOURCE @{\n    SourceName       = field 0 string\n    SourceIdentifier = field 1 $LUID\n}\n\n$TOKEN_STATISTICS = struct $Module TOKEN_STATISTICS @{\n    TokenId            = field 0 $LUID\n    AuthenticationId   = field 1 $LUID\n    ExpirationTime     = field 2 UInt64\n    TokenType          = field 3 $TOKEN_TYPE\n    ImpersonationLevel = field 4 $SECURITY_IMPERSONATION_LEVEL\n    DynamicCharged     = field 5 UInt32\n    DynamicAvailable   = field 6 UInt32\n    GroupCount         = field 7 UInt32\n    PrivilegeCount     = field 8 UInt32\n    ModifiedId         = field 9 $LUID\n}\n\n$TOKEN_USER = struct $Module TOKEN_USER @{\n    User = field 0 $SID_AND_ATTRIBUTES\n}\n#endregion Structs\n\n#region FunctionDefinitions\n$FunctionDefinitions = @(\n    (func kernel32 CloseHandle ([bool]) @(\n        [IntPtr] #_In_ HANDLE hObject\n    ) -EntryPoint CloseHandle -SetLastError),\n\n    (func advapi32 ConvertSidToStringSid ([bool]) @(\n        [IntPtr]                 #_In_  PSID   Sid,\n        [IntPtr].MakeByRefType() #_Out_ LPTSTR *StringSid\n    ) -EntryPoint ConvertSidToStringSid -SetLastError),\n\n    (func advapi32 DuplicateToken ([bool]) @(\n        [IntPtr],                #_In_  HANDLE                       ExistingTokenHandle,\n        [UInt32],                #_In_  SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,\n        [IntPtr].MakeByRefType() #_Out_ PHANDLE                      DuplicateTokenHandle\n    ) -EntryPoint DuplicateToken -SetLastError),\n\n    (func advapi32 GetTokenInformation ([bool]) @(\n        [IntPtr],                #_In_      HANDLE                  TokenHandle\n        [Int32],                 #_In_      TOKEN_INFORMATION_CLASS TokenInformationClass\n        [IntPtr],                #_Out_opt_ LPVOID                  TokenInformation\n        [UInt32],                #_In_      DWORD                   TokenInformationLength\n        [UInt32].MakeByRefType() #_Out_     PDWORD                  ReturnLength\n    ) -EntryPoint GetTokenInformation -SetLastError),\n\n    (func advapi32 ImpersonateLoggedOnUser ([bool]) @(\n        [IntPtr] #_In_ HANDLE hToken\n    ) -EntryPoint ImpersonateLoggedOnUser -SetLastError),\n\n    (func kernel32 OpenProcess ([IntPtr]) @(\n        [UInt32], #_In_ DWORD dwDesiredAccess\n        [bool],   #_In_ BOOL  bInheritHandle\n        [UInt32]  #_In_ DWORD dwProcessId\n    ) -EntryPoint OpenProcess -SetLastError),\n\n    (func advapi32 OpenProcessToken ([bool]) @(\n        [IntPtr],                #_In_  HANDLE  ProcessHandle\n        [UInt32],                #_In_  DWORD   DesiredAccess\n        [IntPtr].MakeByRefType() #_Out_ PHANDLE TokenHandle\n    ) -EntryPoint OpenProcessToken -SetLastError),\n\n    (func kernel32 OpenThread ([IntPtr]) @(\n        [UInt32], #_In_ DWORD dwDesiredAccess\n        [bool],   #_In_ BOOL  bInheritHandle\n        [UInt32]  #_In_ DWORD dwThreadId\n    ) -EntryPoint OpenThread -SetLastError),\n\n    (func advapi32 OpenThreadToken ([bool]) @(\n      [IntPtr],                #_In_  HANDLE  ThreadHandle\n      [UInt32],                #_In_  DWORD   DesiredAccess\n      [bool],                  #_In_  BOOL    OpenAsSelf\n      [IntPtr].MakeByRefType() #_Out_ PHANDLE TokenHandle\n    ) -EntryPoint OpenThreadToken -SetLastError),\n\n    (func advapi32 RevertToSelf ([bool]) @(\n        # No Parameters\n    ) -EntryPoint RevertToSelf -SetLastError)\n)\n\n$Types = $FunctionDefinitions | Add-Win32Type -Module $Module -Namespace AccessToken\n$Advapi32 = $Types['advapi32']\n$Kernel32 = $Types['kernel32']\n#endregion FunctionDefinitions\n\n#region Windows API Functions\n\nfunction CloseHandle\n{\n    <#\n    .SYNOPSIS\n\n    Closes an open object handle.\n\n    .DESCRIPTION\n\n    The CloseHandle function closes handles to the following objects:\n    - Access token\n    - Communications device\n    - Console input\n    - Console screen buffer\n    - Event\n    - File\n    - File mapping\n    - I/O completion port\n    - Job\n    - Mailslot\n    - Memory resource notification\n    - Mutex\n    - Named pipe\n    - Pipe\n    - Process\n    - Semaphore\n    - Thread\n    - Transaction\n    - Waitable timer\n    \n    The documentation for the functions that create these objects indicates that CloseHandle should be used when you are finished with the object, and what happens to pending operations on the object after the handle is closed. In general, CloseHandle invalidates the specified object handle, decrements the object's handle count, and performs object retention checks. After the last handle to an object is closed, the object is removed from the system. \n\n    .PARAMETER Handle\n\n    A valid handle to an open object.\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: PSReflect\n    Optional Dependencies: None\n    \n    (func kernel32 CloseHandle ([bool]) @(\n        [IntPtr] #_In_ HANDLE hObject\n    ) -EntryPoint CloseHandle -SetLastError)\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/ms724211(v=vs.85).aspx\n\n    .EXAMPLE\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $Handle    \n    )\n    \n    $SUCCESS = $Kernel32::CloseHandle($Handle); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n\n    if(-not $SUCCESS) \n    {\n        Write-Debug \"CloseHandle Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n}\n\nfunction ConvertSidToStringSid\n{\n    <#\n    .SYNOPSIS\n\n    The ConvertSidToStringSid function converts a security identifier (SID) to a string format suitable for display, storage, or transmission.\n\n    .DESCRIPTION\n\n    The ConvertSidToStringSid function uses the standard S-R-I-S-S… format for SID strings.\n    \n    .PARAMETER SidPointer\n\n    A pointer to the SID structure to be converted.\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: PSReflect\n    Optional Dependencies: None\n    \n    (func advapi32 ConvertSidToStringSid ([bool]) @(\n        [IntPtr]                 #_In_  PSID   Sid,\n        [IntPtr].MakeByRefType() #_Out_ LPTSTR *StringSid\n    ) -EntryPoint ConvertSidToStringSid -SetLastError)\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa376399(v=vs.85).aspx\n\n    .EXAMPLE\n    #>\n\n    [OutputType([string])]\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $SidPointer    \n    )\n    \n    $StringPtr = [IntPtr]::Zero\n    $Success = $Advapi32::ConvertSidToStringSid($SidPointer, [ref]$StringPtr); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n\n    if(-not $Success) \n    {\n        Write-Verbose \"ConvertSidToStringSid Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n    \n    Write-Output ([System.Runtime.InteropServices.Marshal]::PtrToStringAuto($StringPtr))\n}\n\nfunction DuplicateToken\n{\n    <#\n    .SYNOPSIS\n\n    The DuplicateToken function creates a new access token that duplicates one already in existence.\n\n    .DESCRIPTION\n\n    The DuplicateToken function creates an impersonation token, which you can use in functions such as SetThreadToken and ImpersonateLoggedOnUser. The token created by DuplicateToken cannot be used in the CreateProcessAsUser function, which requires a primary token. To create a token that you can pass to CreateProcessAsUser, use the DuplicateTokenEx function.\n\n    .PARAMETER TokenHandle\n\n    A handle to an access token opened with TOKEN_DUPLICATE access.\n\n    .PARAMETER ImpersonationLevel\n\n    Specifies a SECURITY_IMPERSONATION_LEVEL enumerated type that supplies the impersonation level of the new token. The Default is SecurityImpersonation.\n\n    .NOTES\n    \n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: PSReflect, SECURITY_IMPERSONATION_LEVEL (Enumeration)\n    Optional Dependencies: None\n\n    (func advapi32 DuplicateToken ([bool]) @(\n        [IntPtr]                 #_In_  HANDLE                       ExistingTokenHandle,\n        [UInt32]                 #_In_  SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,\n        [IntPtr].MakeByRefType() #_Out_ PHANDLE                      DuplicateTokenHandle\n    ) -EntryPoint DuplicateToken -SetLastError)\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa446616(v=vs.85).aspx\n\n    .EXAMPLE\n\n    #>\n\n    [OutputType([IntPtr])]\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $TokenHandle,\n\n        [Parameter()]\n        [ValidateSet('None','SecurityAnonymous','SecurityIdentification','SecurityImpersonation','SecurityDelegation')]\n        [string]\n        $ImpersonationLevel = 'SecurityImpersonation'\n    )\n\n    $DuplicateTokenHandle = [IntPtr]::Zero\n\n    $success = $Advapi32::DuplicateToken($TokenHandle, $SECURITY_IMPERSONATION_LEVEL::$ImpersonationLevel, [ref]$DuplicateTokenHandle); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n    \n    if(-not $success)\n    {\n        Write-Debug \"DuplicateToken Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n\n    Write-Output $DuplicateTokenHandle\n}\n\nfunction GetTokenInformation\n{\n    <#\n    .SYNOPSIS\n\n    The GetTokenInformation function retrieves a specified type of information about an access token. The calling process must have appropriate access rights to obtain the information.\n    \n    To determine if a user is a member of a specific group, use the CheckTokenMembership function. To determine group membership for app container tokens, use the CheckTokenMembershipEx function.\n\n    .PARAMETER TokenHandle\n\n    A handle to an access token from which information is retrieved. If TokenInformationClass specifies TokenSource, the handle must have TOKEN_QUERY_SOURCE access. For all other TokenInformationClass values, the handle must have TOKEN_QUERY access.\n\n    .PARAMETER TokenInformationClass\n\n    Specifies a value from the TOKEN_INFORMATION_CLASS enumerated type to identify the type of information the function retrieves. Any callers who check the TokenIsAppContainer and have it return 0 should also verify that the caller token is not an identify level impersonation token. If the current token is not an app container but is an identity level token, you should return AccessDenied.\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Module Dependencies: PSReflect\n    Required Function Dependencies: ConvertSidToStringSid\n    Required Structure Dependencies: TOKEN_USER, SID_AND_ATTRIBUTES, TOKEN_PRIVILEGES, TOKEN_OWNER, TOKEN_SOURCE, LUID, TOKEN_MANDATORY_LABEL\n    Required Enumeration Dependencies: LuidAttributes, TOKEN_TYPE, SECURITY_IMPERSONATION_LEVEL\n    Optional Dependencies: TokenInformationClass (Enum)\n\n    (func advapi32 GetTokenInformation ([bool]) @(\n        [IntPtr],                #_In_      HANDLE                  TokenHandle\n        [Int32],                 #_In_      TOKEN_INFORMATION_CLASS TokenInformationClass\n        [IntPtr],                #_Out_opt_ LPVOID                  TokenInformation\n        [UInt32],                #_In_      DWORD                   TokenInformationLength\n        [UInt32].MakeByRefType() #_Out_     PDWORD                  ReturnLength\n    ) -EntryPoint GetTokenInformation -SetLastError)\n        \n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa446671(v=vs.85).aspx\n\n    .EXAMPLE\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $TokenHandle,\n        \n        [Parameter(Mandatory = $true)]\n        [ValidateSet('TokenUser','TokenGroups','TokenPrivileges','TokenOwner','TokenPrimaryGroup','TokenDefaultDacl','TokenSource','TokenType','TokenImpersonationLevel','TokenStatistics','TokenRestrictedSids','TokenSessionId','TokenGroupsAndPrivileges','TokenSandBoxInert','TokenOrigin','TokenElevationType','TokenLinkedToken','TokenElevation','TokenHasRestrictions','TokenAccessInformation','TokenVirtualizationAllowed','TokenVirtualizationEnabled','TokenIntegrityLevel','TokenUIAccess','TokenMandatoryPolicy','TokenLogonSid','TokenIsAppContainer','TokenCapabilities','TokenAppContainerSid','TokenAppContainerNumber','TokenUserClaimAttributes','TokenDeviceClaimAttributes','TokenDeviceGroups','TokenRestrictedDeviceGroups')]\n        [string]\n        $TokenInformationClass\n    )\n\n    # initial query to determine the necessary buffer size\n    $TokenPtrSize = 0\n    $SUCCESS = $Advapi32::GetTokenInformation($TokenHandle, $TOKEN_INFORMATION_CLASS::$TokenInformationClass, [IntPtr]::Zero, $TokenPtrSize, [ref]$TokenPtrSize); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n\n    [IntPtr]$TokenPtr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($TokenPtrSize)\n\n    # retrieve the proper buffer value\n    $SUCCESS = $Advapi32::GetTokenInformation($TokenHandle, $TOKEN_INFORMATION_CLASS::$TokenInformationClass, $TokenPtr, $TokenPtrSize, [ref]$TokenPtrSize); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n    \n    if(-not $SUCCESS)\n    {\n        [System.Runtime.InteropServices.Marshal]::FreeHGlobal($TokenPtr)\n        throw \"GetTokenInformation Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n\n    switch($TokenInformationClass)\n    {\n        TokenUser\n        {\n            <#\n            The buffer receives a TOKEN_USER structure that contains the user account of the token.\n                ConvertSidToStringSid (Function)\n                TOKEN_USER (Structure)\n                SID_AND_ATTRIBUTES (Structure)\n            #>\n            $TokenUser = $TokenPtr -as $TOKEN_USER\n            $UserSid = ConvertSidToStringSid -SidPointer $TokenUser.User.Sid\n\n            $Sid = New-Object System.Security.Principal.SecurityIdentifier($UserSid)\n            $UserName = $Sid.Translate([System.Security.Principal.NTAccount])\n\n            $obj = New-Object -TypeName psobject\n\n            $obj | Add-Member -MemberType NoteProperty -Name Sid -Value $UserSid\n            $obj | Add-Member -MemberType NoteProperty -Name Name -Value $UserName\n\n            Write-Output $obj\n        }\n        TokenGroups\n        {\n            <#\n            The buffer receives a TOKEN_GROUPS structure that contains the group accounts associated with the token.\n                TOKEN_GROUPS (Structure)\n                SID_AND_ATTRIBUTES (Structure)\n            #>\n            $TokenGroups = ($TokenPtr -as $TOKEN_GROUPS)\n\n            for($i = 0; $i -lt $TokenGroups.GroupCount; $i++)\n            {\n                $obj = New-Object -TypeName psobject\n\n                $obj | Add-Member -MemberType NoteProperty -Name Sid -Value (ConvertSidToStringSid -SidPointer $TokenGroups.Groups[$i].Sid)\n                $obj | Add-Member -MemberType NoteProperty -Name Attributes -Value $TokenGroups.Groups[$i].Attributes\n\n                Write-Output $obj\n            }\n        }\n        TokenPrivileges\n        {\n            <#\n            The buffer receives a TOKEN_PRIVILEGES structure that contains the privileges of the token.\n                TOKEN_PRIVILEGES (Structure)\n                LUID_AND_ATTRIBUTES (Structure)\n                LuidAttributes (Enumeration)\n            #>\n            $TokenPrivileges = $TokenPtr -as $TOKEN_PRIVILEGES\n                \n            for($i = 0; $i -lt $TokenPrivileges.PrivilegeCount; $i++)\n            {\n                $obj = New-Object -TypeName psobject\n                    \n                $obj | Add-Member -MemberType NoteProperty -Name Privilege -Value $TokenPrivileges.Privileges[$i].Luid.LowPart\n                $obj | Add-Member -MemberType NoteProperty -Name Attributes -Value $TokenPrivileges.Privileges[$i].Attributes\n                    \n                Write-Output $obj   \n            }\n\n        }\n        TokenOwner\n        {\n            <#\n            The buffer receives a TOKEN_OWNER structure that contains the default owner security identifier (SID) for newly created objects.\n                ConvertSidToStringSid (Function)\n                TOKEN_OWNER (Structure)\n            #>\n            $TokenOwner = $TokenPtr -as $TOKEN_OWNER\n    \n            if($TokenOwner.Owner -ne $null)\n            {\n                $OwnerSid = ConvertSidToStringSid -SidPointer $TokenOwner.Owner\n                \n                $Sid = New-Object System.Security.Principal.SecurityIdentifier($OwnerSid)\n                $OwnerName = $Sid.Translate([System.Security.Principal.NTAccount])\n\n                $obj = New-Object -TypeName psobject\n\n                $obj | Add-Member -MemberType NoteProperty -Name Sid -Value $OwnerSid\n                $obj | Add-Member -MemberType NoteProperty -Name Name -Value $OwnerName\n\n                Write-Output $obj\n            }\n            else\n            {\n                Write-Output $null\n            }\n        }\n        TokenPrimaryGroup\n        {\n            <#\n            The buffer receives a TOKEN_PRIMARY_GROUP structure that contains the default primary group SID for newly created objects.\n                TOKEN_PRIMARY_GROUP (Structure)\n            #>\n            throw [System.NotImplementedException]\"The $($TokenInformationClass) class is not implemented yet.\"\n        }\n        TokenDefaultDacl\n        {\n            <#\n            The buffer receives a TOKEN_DEFAULT_DACL structure that contains the default DACL for newly created objects.\n                TOKEN_DEFAULT_DACL (Structure)\n                ACL (Structure)\n            #>\n            $Dacl = $TokenPtr -as $TOKEN_DEFAULT_DACL\n            Write-Output $Dacl.DefaultDacl\n        }\n        TokenSource\n        {\n            <#\n            The buffer receives a TOKEN_SOURCE structure that contains the source of the token. TOKEN_QUERY_SOURCE access is needed to retrieve this information.\n                TOKEN_SOURCE (Structure)\n                LUID (Structure)\n            #>\n            \n            Write-Output $TokenPtr\n            #$TokenSource = $TokenPtr -as $TOKEN_SOURCE\n            #Write-Output ($TokenSource.SourceName -join \"\")\n        }\n        TokenType\n        {\n            <#\n            The buffer receives a TOKEN_TYPE value that indicates whether the token is a primary or impersonation token.\n                TOKEN_TYPE (Enumeration)\n            #>\n            if($TokenPtr -ne $null)\n            {\n                Write-Output ([System.Runtime.InteropServices.Marshal]::ReadInt32($TokenPtr) -as $TOKEN_TYPE)\n            }\n        }\n        TokenImpersonationLevel\n        {\n            <#\n            The buffer receives a SECURITY_IMPERSONATION_LEVEL value that indicates the impersonation level of the token. If the access token is not an impersonation token, the function fails.\n                SECURITY_IMPERSONATION_LEVEL (Enumeration)\n            #>\n            Write-Output ([System.Runtime.InteropServices.Marshal]::ReadInt32($TokenPtr) -as $SECURITY_IMPERSONATION_LEVEL)\n        }\n        TokenStatistics\n        {\n            <#\n            The buffer receives a TOKEN_STATISTICS structure that contains various token statistics.\n                TOKEN_STATISTICS (Structure)\n                LUID (Structure)\n                TOKEN_TYPE (Enumeration)\n                SECURITY_IMPERSONATION_LEVEL (Enumeration)\n            #>\n            $TokenStats = $TokenPtr -as $TOKEN_STATISTICS\n\n            $obj = New-Object -TypeName psobject\n\n            $obj | Add-Member -MemberType NoteProperty -Name TokenId -Value $TokenStats.TokenId.LowPart\n            $obj | Add-Member -MemberType NoteProperty -Name AuthenticationId -Value $TokenStats.AuthenticationId.LowPart\n            $obj | Add-Member -MemberType NoteProperty -Name TokenType -Value $TokenStats.TokenType\n            $obj | Add-Member -MemberType NoteProperty -Name ImpersonationLevel -Value $TokenStats.ImpersonationLevel\n            $obj | Add-Member -MemberType NoteProperty -Name DynamicCharged -Value $TokenStats.DynamicCharged\n            $obj | Add-Member -MemberType NoteProperty -Name DynamicAvailable -Value $TokenStats.DynamicAvailable\n            $obj | Add-Member -MemberType NoteProperty -Name GroupCount -Value $TokenStats.GroupCount\n            $obj | Add-Member -MemberType NoteProperty -Name PrivilegeCount -Value $TokenStats.PrivilegeCount\n            $obj | Add-Member -MemberType NoteProperty -Name ModifiedId -Value $TokenStats.ModifiedId.LowPart\n                \n            Write-Output $obj\n        }\n        TokenRestrictedSids\n        {\n            <#\n            The buffer receives a TOKEN_GROUPS structure that contains the list of restricting SIDs in a restricted token.\n                TOKEN_GROUPS (Structure)\n                SID_AND_ATTRIBUTES (Structure)\n            #>\n            $TokenGroups = ($TokenPtr -as $TOKEN_GROUPS)\n\n            for($i = 0; $i -lt $TokenGroups.GroupCount; $i++)\n            {\n                $obj = New-Object -TypeName psobject\n\n                $obj | Add-Member -MemberType NoteProperty -Name Sid -Value (ConvertSidToStringSid -SidPointer $TokenGroups.Groups[$i].Sid)\n                $obj | Add-Member -MemberType NoteProperty -Name Attributes -Value $TokenGroups.Groups[$i].Attributes\n\n                Write-Output $obj\n            }\n        }\n        TokenSessionId\n        {\n            # The buffer receives a DWORD value that indicates the Terminal Services session identifier that is associated with the token.\n            # If the token is associated with the terminal server client session, the session identifier is nonzero.\n            # Windows Server 2003 and Windows XP:  If the token is associated with the terminal server console session, the session identifier is zero.\n            # In a non-Terminal Services environment, the session identifier is zero.\n            # If TokenSessionId is set with SetTokenInformation, the application must have the Act As Part Of the Operating System privilege, and the application must be enabled to set the session ID in a token.\n            Write-Output ([System.Runtime.InteropServices.Marshal]::ReadInt32($TokenPtr))\n        }\n        TokenGroupsAndPrivileges\n        {\n            <#\n            The buffer receives a TOKEN_GROUPS_AND_PRIVILEGES structure that contains the user SID, the group accounts, the restricted SIDs, and the authentication ID associated with the token.\n                TOKEN_GROUPS_AND_PRIVILEGES (Structure)\n                SID_AND_ATTRIBUTES (Structure)\n                LUID (Structure)\n            #>\n            $GroupsAndPrivs = ($TokenPtr -as $TOKEN_GROUPS_AND_PRIVILEGES)\n                \n            $SidList = New-Object -TypeName 'System.Collections.Generic.List[System.Object]'\n\n            for($i = 0; $i -lt $GroupsAndPrivs.SidCount; $i++)\n            {\n                $currentPtr = [IntPtr]($GroupsAndPrivs.Sids.ToInt64() + ($SID_AND_ATTRIBUTES::GetSize() * $i))\n                $SidAndAttr = $currentPtr -as $SID_AND_ATTRIBUTES\n\n                $obj = New-Object -TypeName psobject\n\n                $obj | Add-Member -MemberType NoteProperty -Name Sid -Value (ConvertSidToStringSid -SidPointer $SidAndAttr.Sid)\n                $obj | Add-Member -MemberType NoteProperty -Name Attributes -Value $SidAndAttr.Attributes\n\n                $SidList.Add($obj)\n            }\n                \n            $PrivList = New-Object -TypeName 'System.Collections.Generic.List[System.Object]'\n\n            for($i = 0; $i -lt $GroupsAndPrivs.PrivilegeCount; $i++)\n            {\n                $currentPtr = [IntPtr]($GroupsAndPrivs.Privileges.ToInt64() + ($LUID_AND_ATTRIBUTES::GetSize() * $i))\n                $LuidAndAttr = ($currentPtr -as $LUID_AND_ATTRIBUTES)\n\n                $obj = New-Object -TypeName psobject\n\n                $obj | Add-Member -MemberType NoteProperty -Name Privilege -Value $LuidAndAttr.Luid.LowPart\n                $obj | Add-Member -MemberType NoteProperty -Name Attributes -Value $LuidAndAttr.Attributes\n\n                $PrivList.Add($obj)\n            }\n\n            $obj = New-Object -TypeName psobject\n\n            $obj | Add-Member -MemberType NoteProperty -Name Sids -Value $SidList.ToArray()\n            $obj | Add-Member -MemberType NoteProperty -Name Privilegs -Value $PrivList.ToArray()\n\n            Write-Output $obj\n        }\n        TokenSandBoxInert\n        {\n            # The buffer receives a DWORD value that is nonzero if the token includes the SANDBOX_INERT flag.\n            Write-Output (0 -ne ([System.Runtime.InteropServices.Marshal]::ReadInt32($TokenPtr)))\n        }\n        TokenOrigin\n        {\n            <#\n            The buffer receives a TOKEN_ORIGIN value.\n            If the token resulted from a logon that used explicit credentials, such as passing a name, domain, and password to the LogonUser function, then the TOKEN_ORIGIN structure will contain the ID of the logon session that created it.\n            If the token resulted from network authentication, such as a call to AcceptSecurityContext or a call to LogonUser with dwLogonType set to LOGON32_LOGON_NETWORK or LOGON32_LOGON_NETWORK_CLEARTEXT, then this value will be zero.\n                TOKEN_ORIGIN (Structure)\n                LUID (Structure)\n            #>\n            $TokenOrigin = $TokenPtr -as $LUID\n            Write-Output $TokenOrigin.LowPart\n        }\n        TokenElevationType\n        {\n            <#\n            The buffer receives a TOKEN_ELEVATION_TYPE value that specifies the elevation level of the token.\n                TOKEN_ELEVATION_TYPE (Enumeration)\n            #>\n            Write-Output ([System.Runtime.InteropServices.Marshal]::ReadInt32($TokenPtr) -as $TOKEN_ELEVATION_TYPE)\n        }\n        TokenLinkedToken\n        {\n            <#\n            The buffer receives a TOKEN_LINKED_TOKEN structure that contains a handle to another token that is linked to this token.\n                TOKEN_LINKED_TOKEN (Structure)\n            #>\n            Write-Output ($TokenPtr -as $TOKEN_LINKED_TOKEN).LinkedToken\n        }\n        TokenElevation\n        {\n            <#\n            The buffer receives a TOKEN_ELEVATION structure that specifies whether the token is elevated.                                    \n                TOKEN_ELEVATION (Structure)\n            #>\n            Write-Output (($TokenPtr -as $TOKEN_ELEVATION).TokenIsElevated -ne 0)\n        }\n        TokenHasRestrictions\n        {\n            # The buffer receives a DWORD value that is nonzero if the token has ever been filtered.\n            Write-Output (0 -ne ([System.Runtime.InteropServices.Marshal]::ReadInt32($TokenPtr)))\n        }\n        TokenAccessInformation\n        {\n            <#\n            The buffer receives a TOKEN_ACCESS_INFORMATION structure that specifies security information contained in the token.\n                TOKEN_ACCESS_INFORMATION (Structure)\n                SID_AND_ATTRIBUTES_HASH (Structure)\n                SID_HASH_ENTRY (Structure)\n                TOKEN_PRIVILEGES (Structure)\n                LUID_AND_ATTRIBUTES (Structure)\n                LUID (Structure)\n                TOKEN_TYPE (Enumeration)\n                SECURITY_IMPERSONATION_LEVEL (Enumeration)\n                TOKEN_MANDATORY_POLICY (Structure)\n            #>\n            <#\n            $TokenAccessInfo = ($TokenPtr -as $TOKEN_ACCESS_INFORMATION)\n                \n            $obj = New-Object -TypeName psobject\n\n            $obj | Add-Member -MemberType NoteProperty -Name SidHash -Value ($TokenAccessInfo.SidHash -as $SID_AND_ATTRIBUTES_HASH)\n            $obj | Add-Member -MemberType NoteProperty -Name RestrictedSidHash -Value ($TokenAccessInfo.RestrictedSidHash -as $SID_AND_ATTRIBUTES_HASH)\n            $obj | Add-Member -MemberType NoteProperty -Name Privileges -Value ($TokenAccessInfo.Privileges -as $TOKEN_PRIVILEGES)\n            $obj | Add-Member -MemberType NoteProperty -Name AuthenticationId -Value $TokenAccessInfo.AuthenticationId.LowPart\n            $obj | Add-Member -MemberType NoteProperty -Name TokenType -Value $TokenAccessInfo.TokenType\n            $obj | Add-Member -MemberType NoteProperty -Name ImpersonationLevel -Value $TokenAccessInfo.ImpersonationLevel\n            $obj | Add-Member -MemberType NoteProperty -Name AppContainerNumber -Value $TokenAccessInfo.AppContainerNumber\n            $obj | Add-Member -MemberType NoteProperty -Name PackageSid -Value (ConvertSidToStringSid -SidPointer $TokenAccessInfo.PackageSid)\n            $obj | Add-Member -MemberType NoteProperty -Name CapabilitiesHash -Value ($TokenAccessInfo.CapabilitiesHash -as $SID_AND_ATTRIBUTES_HASH)\n            $obj | Add-Member -MemberType NoteProperty -Name TrustLevelSid -Value (ConvertSidToStringSid -SidPointer $TokenAccessInfo.TrustLevelSid)\n\n            Write-Output $obj\n            #>\n\n            Write-Output $TokenPtr\n            #throw [System.NotImplementedException]\"The $($TokenInformationClass) class is not implemented yet.\"\n        }\n        TokenVirtualizationAllowed\n        {\n            # The buffer receives a DWORD value that is nonzero if virtualization is allowed for the token.\n            Write-Output (0 -ne ([System.Runtime.InteropServices.Marshal]::ReadInt32($TokenPtr)))\n        }\n        TokenVirtualizationEnabled\n        {\n            # The buffer receives a DWORD value that is nonzero if virtualization is enabled for the token.\n            Write-Output (0 -ne ([System.Runtime.InteropServices.Marshal]::ReadInt32($TokenPtr)))\n        }\n        TokenIntegrityLevel\n        {\n            <#\n            The buffer receives a TOKEN_MANDATORY_LABEL structure that specifies the token's integrity level.\n                TOKEN_MANDATORY_LABEL\n                ConvertSidToStringSid\n            #>\n            $TokenIntegrity = $TokenPtr -as $TOKEN_MANDATORY_LABEL\n\n            switch(ConvertSidToStringSid -SidPointer $TokenIntegrity.Label.Sid)\n            {\n                S-1-16-0\n                {\n                    Write-Output \"UNTRUSTED_MANDATORY_LEVEL\"\n                }\n                S-1-16-4096\n                {\n                    Write-Output \"LOW_MANDATORY_LEVEL\"\n                }\n                S-1-16-8192\n                {\n                    Write-Output \"MEDIUM_MANDATORY_LEVEL\"\n                }\n                S-1-16-8448\n                {\n                    Write-Output \"MEDIUM_PLUS_MANDATORY_LEVEL\"\n                }\n                S-1-16-12288\n                {\n                    Write-Output \"HIGH_MANDATORY_LEVEL\"\n                }\n                S-1-16-16384\n                {\n                    Write-Output \"SYSTEM_MANDATORY_LEVEL\"\n                }\n                S-1-16-20480\n                {\n                    Write-Output \"PROTECTED_PROCESS_MANDATORY_LEVEL\"\n                }\n                S-1-16-28672\n                {\n                    Write-Output \"SECURE_PROCESS_MANDATORY_LEVEL\"\n                }\n            }\n        }\n        TokenUIAccess\n        {\n            # The buffer receives a DWORD value that is nonzero if the token has the UIAccess flag set.\n            Write-Output (0 -ne ([System.Runtime.InteropServices.Marshal]::ReadInt32($TokenPtr)))\n        }\n        TokenMandatoryPolicy\n        {\n            <#\n            The buffer receives a TOKEN_MANDATORY_POLICY structure that specifies the token's mandatory integrity policy.\n                TOKEN_MANDATORY_POLICY\n                TOKENMANDATORYPOLICY\n            #>\n            $MandatoryPolicy = $TokenPtr -as $TOKEN_MANDATORY_POLICY\n            Write-Output $MandatoryPolicy.Policy\n        }\n        TokenLogonSid\n        {\n            <#\n            The buffer receives a TOKEN_GROUPS structure that specifies the token's logon SID.\n                TOKEN_GROUPS (Structure)\n                SID_AND_ATTRIBUTES (Structure)\n            #>\n            $TokenGroups = ($TokenPtr -as $TOKEN_GROUPS)\n\n            for($i = 0; $i -lt $TokenGroups.GroupCount; $i++)\n            {\n                $obj = New-Object -TypeName psobject\n\n                $obj | Add-Member -MemberType NoteProperty -Name Sid -Value (ConvertSidToStringSid -SidPointer $TokenGroups.Groups[$i].Sid)\n                $obj | Add-Member -MemberType NoteProperty -Name Attributes -Value $TokenGroups.Groups[$i].Attributes\n\n                Write-Output $obj\n            }\n        }\n        TokenIsAppContainer\n        {\n            # The buffer receives a DWORD value that is nonzero if the token is an app container token. Any callers who check the TokenIsAppContainer and have it return 0 should also verify that the caller token is not an identify level impersonation token. If the current token is not an app container but is an identity level token, you should return AccessDenied.\n            Write-Output (0 -ne ([System.Runtime.InteropServices.Marshal]::ReadInt32($TokenPtr)))\n        }\n        TokenCapabilities\n        {\n            <#\n            The buffer receives a TOKEN_GROUPS structure that contains the capabilities associated with the token.\n                TOKEN_GROUPS (Structure)\n                SID_AND_ATTRIBUTES (Structure)\n            #>\n            $TokenGroups = ($TokenPtr -as $TOKEN_GROUPS)\n\n            for($i = 0; $i -lt $TokenGroups.GroupCount; $i++)\n            {\n                $obj = New-Object -TypeName psobject\n\n                $obj | Add-Member -MemberType NoteProperty -Name Sid -Value (ConvertSidToStringSid -SidPointer $TokenGroups.Groups[$i].Sid)\n                $obj | Add-Member -MemberType NoteProperty -Name Attributes -Value $TokenGroups.Groups[$i].Attributes\n\n                Write-Output $obj\n            }\n        }\n        TokenAppContainerSid\n        {\n            <#\n            The buffer receives a TOKEN_APPCONTAINER_INFORMATION structure that contains the AppContainerSid associated with the token. If the token is not associated with an app container, the TokenAppContainer member of the TOKEN_APPCONTAINER_INFORMATION structure points to NULL.\n                TOKEN_APPCONTAINER_INFORMATION (Structure)\n            #>\n            Write-Output ($TokenPtr -as $TOKEN_APPCONTAINER_INFORMATION)\n        }\n        TokenAppContainerNumber\n        {\n            # The buffer receives a DWORD value that includes the app container number for the token. For tokens that are not app container tokens, this value is zero.\n            Write-Output ([System.Runtime.InteropServices.Marshal]::ReadInt32($TokenPtr))\n        }\n        TokenUserClaimAttributes\n        {\n            <#\n            The buffer receives a CLAIM_SECURITY_ATTRIBUTES_INFORMATION structure that contains the user claims associated with the token.\n                CLAIM_SECURITY_ATTRIBUTES_INFORMATION (Structure)\n                CLAIM_SECURITY_ATTRIBUTE_V1 (Structure)\n                CLAIM_SECURITY_ATTRIBUTE_FQBN_VALUE (Structure)\n                CLAIM_SECURITY_ATTRIBUTE_OCTET_STRING_VALUE (Structure)\n            #>\n            <#\n            $AttributeInformation = $TokenPtr -as $CLAIM_SECURITY_ATTRIBUTES_INFORMATION\n                \n            if($AttributeInformation.AttributeCount -ne 0)\n            {\n\n            }\n            #>\n            throw [System.NotImplementedException]\"The $($TokenInformationClass) class is not implemented yet.\"\n        }\n        TokenDeviceClaimAttributes\n        {\n            <#\n            The buffer receives a CLAIM_SECURITY_ATTRIBUTES_INFORMATION structure that contains the device claims associated with the token.\n                CLAIM_SECURITY_ATTRIBUTES_INFORMATION (Structure)\n                CLAIM_SECURITY_ATTRIBUTE_V1 (Structure)\n                CLAIM_SECURITY_ATTRIBUTE_FQBN_VALUE (Structure)\n                CLAIM_SECURITY_ATTRIBUTE_OCTET_STRING_VALUE (Structure)\n            #>\n            <#\n            $AttributeInformation = $TokenPtr -as $CLAIM_SECURITY_ATTRIBUTES_INFORMATION\n                \n            if($AttributeInformation.AttributeCount -ne 0)\n            {\n\n            }\n            #>\n            throw [System.NotImplementedException]\"The $($TokenInformationClass) class is not implemented yet.\"\n        }\n        TokenDeviceGroups\n        {\n            <#\n            The buffer receives a TOKEN_GROUPS structure that contains the device groups that are associated with the token.\n                TOKEN_GROUPS (Structure)\n                SID_AND_ATTRIBUTES (Structure)\n            #>\n            #Write-Output ($TokenPtr -as $TOKEN_GROUPS)\n            $TokenGroups = ($TokenPtr -as $TOKEN_GROUPS)\n\n            for($i = 0; $i -lt $TokenGroups.GroupCount; $i++)\n            {\n                $obj = New-Object -TypeName psobject\n\n                $obj | Add-Member -MemberType NoteProperty -Name Sid -Value (ConvertSidToStringSid -SidPointer $TokenGroups.Groups[$i].Sid)\n                $obj | Add-Member -MemberType NoteProperty -Name Attributes -Value $TokenGroups.Groups[$i].Attributes\n\n                Write-Output $obj\n            }\n        }\n        TokenRestrictedDeviceGroups\n        {\n            <#\n            The buffer receives a TOKEN_GROUPS structure that contains the restricted device groups that are associated with the token.\n                TOKEN_GROUPS (Structure)\n                SID_AND_ATTRIBUTES (Structure)\n            #>\n            $TokenGroups = ($TokenPtr -as $TOKEN_GROUPS)\n\n            for($i = 0; $i -lt $TokenGroups.GroupCount; $i++)\n            {\n                $obj = New-Object -TypeName psobject\n\n                $obj | Add-Member -MemberType NoteProperty -Name Sid -Value (ConvertSidToStringSid -SidPointer $TokenGroups.Groups[$i].Sid)\n                $obj | Add-Member -MemberType NoteProperty -Name Attributes -Value $TokenGroups.Groups[$i].Attributes\n\n                Write-Output $obj\n            }\n        }\n    }\n\n    [System.Runtime.InteropServices.Marshal]::FreeHGlobal($TokenPtr)\n}\n\nfunction ImpersonateLoggedOnUser\n{\n    <#\n    .SYNOPSIS\n\n    The ImpersonateLoggedOnUser function lets the calling thread impersonate the security context of a logged-on user. The user is represented by a token handle.\n\n    .DESCRIPTION\n\n    The impersonation lasts until the thread exits or until it calls RevertToSelf.\n    \n    The calling thread does not need to have any particular privileges to call ImpersonateLoggedOnUser.\n    \n    If the call to ImpersonateLoggedOnUser fails, the client connection is not impersonated and the client request is made in the security context of the process. If the process is running as a highly privileged account, such as LocalSystem, or as a member of an administrative group, the user may be able to perform actions they would otherwise be disallowed. Therefore, it is important to always check the return value of the call, and if it fails, raise an error; do not continue execution of the client request.\n    \n    All impersonate functions, including ImpersonateLoggedOnUser allow the requested impersonation if one of the following is true:\n    - The requested impersonation level of the token is less than SecurityImpersonation, such as SecurityIdentification or SecurityAnonymous.\n    - The caller has the SeImpersonatePrivilege privilege.\n    - A process (or another process in the caller's logon session) created the token using explicit credentials through LogonUser or LsaLogonUser function.\n    - The authenticated identity is same as the caller.\n    \n    Windows XP with SP1 and earlier:  The SeImpersonatePrivilege privilege is not supported.\n\n    .PARAMETER TokenHandle\n\n    A handle to a primary or impersonation access token that represents a logged-on user. This can be a token handle returned by a call to LogonUser, CreateRestrictedToken, DuplicateToken, DuplicateTokenEx, OpenProcessToken, or OpenThreadToken functions. If hToken is a handle to a primary token, the token must have TOKEN_QUERY and TOKEN_DUPLICATE access. If hToken is a handle to an impersonation token, the token must have TOKEN_QUERY and TOKEN_IMPERSONATE access.\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: PSReflect\n    Optional Dependencies: None\n\n    (func advapi32 ImpersonateLoggedOnUser ([bool]) @(\n        [IntPtr] #_In_ HANDLE hToken\n    ) -EntryPoint ImpersonateLoggedOnUser -SetLastError)\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa378612(v=vs.85).aspx\n\n    .EXAMPLE\n\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $TokenHandle\n    )\n\n    $SUCCESS = $Advapi32::ImpersonateLoggedOnUser($TokenHandle); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n    \n    if(-not $SUCCESS)\n    {\n        throw \"ImpersonateLoggedOnUser Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n}\n\nfunction OpenProcess\n{\n    <#\n    .SYNOPSIS\n\n    Opens an existing local process object.\n\n    .DESCRIPTION\n\n    To open a handle to another local process and obtain full access rights, you must enable the SeDebugPrivilege privilege.\n    The handle returned by the OpenProcess function can be used in any function that requires a handle to a process, such as the wait functions, provided the appropriate access rights were requested.\n    When you are finished with the handle, be sure to close it using the CloseHandle function.\n\n    .PARAMETER ProcessId\n\n    The identifier of the local process to be opened.\n    If the specified process is the System Process (0x00000000), the function fails and the last error code is ERROR_INVALID_PARAMETER. If the specified process is the Idle process or one of the CSRSS processes, this function fails and the last error code is ERROR_ACCESS_DENIED because their access restrictions prevent user-level code from opening them.\n\n    .PARAMETER DesiredAccess\n\n    The access to the process object. This access right is checked against the security descriptor for the process. This parameter can be one or more of the process access rights.\n    If the caller has enabled the SeDebugPrivilege privilege, the requested access is granted regardless of the contents of the security descriptor.\n\n    .PARAMETER InheritHandle\n\n    If this value is TRUE, processes created by this process will inherit the handle. Otherwise, the processes do not inherit this handle.\n\n    .NOTES\n    \n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: PSReflect, PROCESS_ACCESS (Enumeration)\n    Optional Dependencies: None\n\n    (func kernel32 OpenProcess ([IntPtr]) @(\n        [UInt32], #_In_ DWORD dwDesiredAccess\n        [bool],   #_In_ BOOL  bInheritHandle\n        [UInt32]  #_In_ DWORD dwProcessId\n    ) -EntryPoint OpenProcess -SetLastError)\n        \n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/ms684320(v=vs.85).aspx\n    \n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/ms684880(v=vs.85).aspx\n\n    .EXAMPLE\n    #>\n\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [UInt32]\n        $ProcessId,\n        \n        [Parameter(Mandatory = $true)]\n        [ValidateSet('PROCESS_TERMINATE','PROCESS_CREATE_THREAD','PROCESS_VM_OPERATION','PROCESS_VM_READ','PROCESS_VM_WRITE','PROCESS_DUP_HANDLE','PROCESS_CREATE_PROCESS','PROCESS_SET_QUOTA','PROCESS_SET_INFORMATION','PROCESS_QUERY_INFORMATION','PROCESS_SUSPEND_RESUME','PROCESS_QUERY_LIMITED_INFORMATION','DELETE','READ_CONTROL','WRITE_DAC','WRITE_OWNER','SYNCHRONIZE','PROCESS_ALL_ACCESS')]\n        [string[]]\n        $DesiredAccess,\n        \n        [Parameter()]\n        [bool]\n        $InheritHandle = $false\n    )\n\n    # Calculate Desired Access Value\n    $dwDesiredAccess = 0\n\n    foreach($val in $DesiredAccess)\n    {\n        $dwDesiredAccess = $dwDesiredAccess -bor $PROCESS_ACCESS::$val\n    }\n\n    $hProcess = $Kernel32::OpenProcess($dwDesiredAccess, $InheritHandle, $ProcessId); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n\n    if($hProcess -eq 0) \n    {\n        throw \"OpenProcess Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n    \n    Write-Output $hProcess\n}\n\nfunction OpenProcessToken\n{ \n    <#\n    .SYNOPSIS\n\n    The OpenProcessToken function opens the access token associated with a process.\n\n    .PARAMETER ProcessHandle\n\n    A handle to the process whose access token is opened. The process must have the PROCESS_QUERY_INFORMATION access permission.\n\n    .PARAMETER DesiredAccess\n\n    Specifies an access mask that specifies the requested types of access to the access token. These requested access types are compared with the discretionary access control list (DACL) of the token to determine which accesses are granted or denied.\n    For a list of access rights for access tokens, see Access Rights for Access-Token Objects.\n\n    .NOTES\n    \n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: PSReflect, TOKEN_ACCESS (Enumeration)\n    Optional Dependencies: None\n\n    (func advapi32 OpenProcessToken ([bool]) @(\n        [IntPtr],                #_In_  HANDLE  ProcessHandle\n        [UInt32],                #_In_  DWORD   DesiredAccess\n        [IntPtr].MakeByRefType() #_Out_ PHANDLE TokenHandle\n    ) -EntryPoint OpenProcessToken -SetLastError)\n        \n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa379295(v=vs.85).aspx\n    \n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa374905(v=vs.85).aspx\n\n    .EXAMPLE\n    #>\n\n    [OutputType([IntPtr])]\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $ProcessHandle,\n        \n        [Parameter(Mandatory = $true)]\n        [ValidateSet('TOKEN_ASSIGN_PRIMARY','TOKEN_DUPLICATE','TOKEN_IMPERSONATE','TOKEN_QUERY','TOKEN_QUERY_SOURCE','TOKEN_ADJUST_PRIVILEGES','TOKEN_ADJUST_GROUPS','TOKEN_ADJUST_DEFAULT','TOKEN_ADJUST_SESSIONID','DELETE','READ_CONTROL','WRITE_DAC','WRITE_OWNER','SYNCHRONIZE','STANDARD_RIGHTS_REQUIRED','TOKEN_ALL_ACCESS')]\n        [string[]]\n        $DesiredAccess  \n    )\n    \n    # Calculate Desired Access Value\n    $dwDesiredAccess = 0\n\n    foreach($val in $DesiredAccess)\n    {\n        $dwDesiredAccess = $dwDesiredAccess -bor $TOKEN_ACCESS::$val\n    }\n\n    $hToken = [IntPtr]::Zero\n    $Success = $Advapi32::OpenProcessToken($ProcessHandle, $dwDesiredAccess, [ref]$hToken); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n\n    if(-not $Success) \n    {\n        throw \"OpenProcessToken Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n    \n    Write-Output $hToken\n}\n\nfunction OpenThread\n{\n    <#\n    .SYNOPSIS\n\n    Opens an existing thread object.\n\n    .DESCRIPTION\n\n    The handle returned by OpenThread can be used in any function that requires a handle to a thread, such as the wait functions, provided you requested the appropriate access rights. The handle is granted access to the thread object only to the extent it was specified in the dwDesiredAccess parameter.\n    When you are finished with the handle, be sure to close it by using the CloseHandle function.\n\n    .PARAMETER ThreadId\n\n    The identifier of the thread to be opened.\n\n    .PARAMETER DesiredAccess\n\n    The access to the thread object. This access right is checked against the security descriptor for the thread. This parameter can be one or more of the thread access rights.\n    If the caller has enabled the SeDebugPrivilege privilege, the requested access is granted regardless of the contents of the security descriptor.\n\n    .PARAMETER InheritHandle\n\n    If this value is TRUE, processes created by this process will inherit the handle. Otherwise, the processes do not inherit this handle.\n    \n    .NOTES\n    \n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: PSReflect, THREAD_ACCESS (Enumeration)\n    Optional Dependencies: None\n\n    (func kernel32 OpenThread ([IntPtr]) @(\n        [UInt32], #_In_ DWORD dwDesiredAccess\n        [bool],   #_In_ BOOL  bInheritHandle\n        [UInt32]  #_In_ DWORD dwThreadId\n    ) -EntryPoint OpenThread -SetLastError)\n        \n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/ms684335(v=vs.85).aspx\n    \n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/ms686769(v=vs.85).aspx\n\n    .EXAMPLE\n    #>\n\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [UInt32]\n        $ThreadId,\n        \n        [Parameter(Mandatory = $true)]\n        [ValidateSet('THREAD_TERMINATE','THREAD_SUSPEND_RESUME','THREAD_GET_CONTEXT','THREAD_SET_CONTEXT','THREAD_SET_INFORMATION','THREAD_QUERY_INFORMATION','THREAD_SET_THREAD_TOKEN','THREAD_IMPERSONATE','THREAD_DIRECT_IMPERSONATION','THREAD_SET_LIMITED_INFORMATION','THREAD_QUERY_LIMITED_INFORMATION','DELETE','READ_CONTROL','WRITE_DAC','WRITE_OWNER','SYNCHRONIZE','THREAD_ALL_ACCESS')]\n        [string[]]\n        $DesiredAccess,\n        \n        [Parameter()]\n        [bool]\n        $InheritHandle = $false\n    )\n    \n    # Calculate Desired Access Value\n    $dwDesiredAccess = 0\n    \n    foreach($val in $DesiredAccess)\n    {\n        $dwDesiredAccess = $dwDesiredAccess -bor $THREAD_ACCESS::$val\n    }\n\n    $hThread = $Kernel32::OpenThread($dwDesiredAccess, $InheritHandle, $ThreadId); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n\n    if($hThread -eq 0) \n    {\n        throw \"OpenThread Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n    \n    Write-Output $hThread\n}\n\nfunction OpenThreadToken\n{\n    <#\n    .SYNOPSIS\n\n    The OpenThreadToken function opens the access token associated with a thread\n\n    .DESCRIPTION\n\n    Tokens with the anonymous impersonation level cannot be opened.\n    Close the access token handle returned through the Handle parameter by calling CloseHandle.\n\n    .PARAMETER ThreadHandle\n\n    A handle to the thread whose access token is opened.\n\n    .PARAMETER DesiredAccess\n\n    Specifies an access mask that specifies the requested types of access to the access token. These requested access types are reconciled against the token's discretionary access control list (DACL) to determine which accesses are granted or denied.\n\n    .PARAMETER OpenAsSelf\n\n    TRUE if the access check is to be made against the process-level security context.\n    FALSE if the access check is to be made against the current security context of the thread calling the OpenThreadToken function.\n    The OpenAsSelf parameter allows the caller of this function to open the access token of a specified thread when the caller is impersonating a token at SecurityIdentification level. Without this parameter, the calling thread cannot open the access token on the specified thread because it is impossible to open executive-level objects by using the SecurityIdentification impersonation level.\n\n    .NOTES\n    \n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: PSReflect, $TOKEN_ACCESS (Enumeration)\n    Optional Dependencies: None\n\n    (func advapi32 OpenThreadToken ([bool]) @(\n      [IntPtr],                #_In_  HANDLE  ThreadHandle\n      [UInt32],                #_In_  DWORD   DesiredAccess\n      [bool],                  #_In_  BOOL    OpenAsSelf\n      [IntPtr].MakeByRefType() #_Out_ PHANDLE TokenHandle\n    ) -EntryPoint OpenThreadToken -SetLastError)\n        \n    .LINK\n    \n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa379296(v=vs.85).aspx\n    \n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa374905(v=vs.85).aspx\n\n    .EXAMPLE\n    #>\n\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $ThreadHandle,\n        \n        [Parameter(Mandatory = $true)]\n        [ValidateSet('TOKEN_ASSIGN_PRIMARY','TOKEN_DUPLICATE','TOKEN_IMPERSONATE','TOKEN_QUERY','TOKEN_QUERY_SOURCE','TOKEN_ADJUST_PRIVILEGES','TOKEN_ADJUST_GROUPS','TOKEN_ADJUST_DEFAULT','TOKEN_ADJUST_SESSIONID','DELETE','READ_CONTROL','WRITE_DAC','WRITE_OWNER','SYNCHRONIZE','STANDARD_RIGHTS_REQUIRED','TOKEN_ALL_ACCESS')]\n        [string[]]\n        $DesiredAccess,\n        \n        [Parameter()]\n        [bool]\n        $OpenAsSelf = $false   \n    )\n    \n    # Calculate Desired Access Value\n    $dwDesiredAccess = 0\n\n    foreach($val in $DesiredAccess)\n    {\n        $dwDesiredAccess = $dwDesiredAccess -bor $TOKEN_ACCESS::$val\n    }\n\n    $hToken = [IntPtr]::Zero\n    $Success = $Advapi32::OpenThreadToken($ThreadHandle, $dwDesiredAccess, $OpenAsSelf, [ref]$hToken); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n\n    if(-not $Success) \n    {\n        throw \"OpenThreadToken Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n    \n    Write-Output $hToken\n}\n\nfunction RevertToSelf\n{\n    <#\n    .SYNOPSIS\n\n    The RevertToSelf function terminates the impersonation of a client application.\n\n    .DESCRIPTION\n\n    A process should call the RevertToSelf function after finishing any impersonation begun by using the DdeImpersonateClient, ImpersonateDdeClientWindow, ImpersonateLoggedOnUser, ImpersonateNamedPipeClient, ImpersonateSelf, ImpersonateAnonymousToken or SetThreadToken function.\n    \n    An RPC server that used the RpcImpersonateClient function to impersonate a client must call the RpcRevertToSelf or RpcRevertToSelfEx to end the impersonation.\n    \n    If RevertToSelf fails, your application continues to run in the context of the client, which is not appropriate. You should shut down the process if RevertToSelf fails.\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: PSReflect\n    Optional Dependencies: None\n\n    (func advapi32 RevertToSelf ([bool]) @(\n    \n    ) -EntryPoint RevertToSelf -SetLastError)\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa379317(v=vs.85).aspx\n\n    .EXAMPLE\n\n        [System.Security.Principal.WindowsIdentity]::GetCurrent().Name\n        NT AUTHORITY\\SYSTEM\n\n        RevertToSelf\n\n        [System.Security.Principal.WindowsIdentity]::GetCurrent().Name\n        hunt.local\\jared\n    #>\n\n    [CmdletBinding()]\n    param\n    (\n\n    )\n\n    $SUCCESS = $Advapi32::RevertToSelf(); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n    \n    if(-not $SUCCESS)\n    {\n        throw \"RevertToSelf Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n}\n\n#endregion Windows API Functions\n\nStart-AceScript -Uri https://10.182.18.200 -SweepId $args[0] -ScanId ([Guid]::NewGuid()) -RoutingKey siem -Thumbprint 8D1DB3B7B85B6F9E9DE87B291DF66692A10240AE"
  },
  {
    "path": "ACE-Management/PS-ACE/Scripts/ACE_Get-ArpCache.ps1",
    "content": "﻿function Start-AceScript\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $SweepId,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $ScanId,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $RoutingKey,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Thumbprint\n    )\n\n    $HostFQDN = Get-WmiObject Win32_ComputerSystem -Property 'Name','Domain' | ForEach-Object {\"$($_.Name).$($_.Domain)\"}\n    $ResultDate = (Get-Date).ToString(\"yyyyMMddThhmmssmsmsZ\")\n\n    $dataList = New-Object -TypeName System.Collections.Generic.List['string']\n\n    foreach($o in (Get-ArpCache))\n    {\n        $o.Add('ComputerName', $HostFQDN)\n        $o.Add('ScanType', 'ArpCache')\n        $o.Add('SweepId', $SweepId)\n        $o.Add('ScanId', $ScanId)\n        $o.Add('ResultDate', $ResultDate)\n\n        $message = ConvertTo-JsonV2 -InputObject $o\n        $dataList.Add($message)\n    }\n\n    $props = @{\n        ComputerName = $HostFQDN\n        ScanType     = 'ArpCache'\n        RoutingKey   = $RoutingKey\n        ResultDate   = $ResultDate\n        ScanId       = $ScanId\n        Data         = $dataList.ToArray()\n    }\n\n    $body = (ConvertTo-JsonV2 -InputObject $props)\n    \n    #Write-Output $body\n    \n    Invoke-AceWebRequest -Thumbprint $Thumbprint -Uri \"$($Uri)/ace/result/$($SweepId)\" -Body $body\n}\n\nfunction ConvertTo-JsonV2 \n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        $InputObject\n    )\n\n    Begin \n    {\n        $null = [System.Reflection.Assembly]::LoadWithPartialName(\"System.Web.Extensions\")\n        $Serializer = New-Object System.Web.Script.Serialization.JavaScriptSerializer\n    }\n\n    Process \n    {\n        try \n        {\n            $Serializer.Serialize($InputObject)\n        } \n        catch \n        {\n            Write-Error $_\n        }    \n    }\n}\n\nfunction Invoke-AceWebRequest\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Thumbprint,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Body\n    )\n\n    [Net.ServicePointManager]::ServerCertificateValidationCallback = {\n        $Thumbprint = $Thumbprint\n        $certificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]$args[1]\n    \n        if ($certificate -eq $null)\n        {\n            $Host.UI.WriteErrorLine(\"Null certificate.\")\n            return $true\n        }\n    \n        if ($certificate.Thumbprint -eq $Thumbprint)\n        {\n            return $true\n        }\n        else\n        {\n            $Host.UI.WriteErrorLine(\"Thumbprint mismatch. Certificate thumbprint $($certificate.Thumbprint)\")\n        }\n    \n        return $false\n    }\n\n    try\n    {\n        Write-Host \"URI: $($Uri)\"\n\n        # Create web request\n        $WebRequest = [Net.WebRequest]::Create($uri)\n        $WebRequest.Method = 'Post'\n        $WebRequest.ContentType = 'application/json'\n        $WebRequest.Headers.Add('X-API-Version:1.0')\n\n        $byteArray = [System.Text.Encoding]::UTF8.GetBytes($Body)\n        $Webrequest.ContentLength = $byteArray.Length\n        \n        $dataStream = $Webrequest.GetRequestStream()            \n        $dataStream.Write($byteArray, 0, $byteArray.Length)\n        $dataStream.Close()\n\n        # Get response stream\n        $ResponseStream = $Webrequest.GetResponse().GetResponseStream()\n    \n        # Create a stream reader and read the stream returning the string value.\n        $StreamReader = New-Object System.IO.StreamReader -ArgumentList $ResponseStream\n        $StreamReader.ReadToEnd()\n    }\n    catch\n    {\n        Write-Error \"Failed: $($_.exception.innerexception.message)\"\n    }\n}\n\nfunction Get-ArpCache\n{\n    <#\n    .SYNOPSIS\n\n    Gets the contents of the ARP Cache.\n\n    .DESCRIPTION\n    \n    The Get-ArpCache function retreives the contents of the system's ARP Cache. The ARP Cache contains cached mappings from IPv4 Addresses to their Physical Address (MAC Address).\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: None\n    Optional Dependencies: None\n\n    .EXAMPLE\n\n    Get-ArpCache\n\n    AdapterIndex       : 1\n    PhysicalAddress    : 00-00-00-00-00-00\n    IpAddress          : 224.0.0.22\n    Type               : STATIC\n    AdapterServiceName : e1iexpress\n    AdapterMacAddress  : 00:0C:29:3A:DF:39\n    AdapterType        : Ethernet 802.3\n    AdapterName        : Intel(R) 82574L Gigabit Network Connection\n    AdapterSpeed       : 1000000000\n\n    AdapterIndex       : 1\n    PhysicalAddress    : 00-00-00-00-00-00\n    IpAddress          : 224.0.0.252\n    Type               : STATIC\n    AdapterServiceName : e1iexpress\n    AdapterMacAddress  : 00:0C:29:3A:DF:39\n    AdapterType        : Ethernet 802.3\n    AdapterName        : Intel(R) 82574L Gigabit Network Connection\n    AdapterSpeed       : 1000000000\n\n    AdapterIndex       : 1\n    PhysicalAddress    : 00-00-00-00-00-00\n    IpAddress          : 239.255.255.250\n    Type               : STATIC\n    AdapterServiceName : e1iexpress\n    AdapterMacAddress  : 00:0C:29:3A:DF:39\n    AdapterType        : Ethernet 802.3\n    AdapterName        : Intel(R) 82574L Gigabit Network Connection\n    AdapterSpeed       : 1000000000\n    #>\n\n    $Entries = GetIpNetTable\n    \n    foreach($Entry in $Entries)\n    {\n        $Adapter = Get-WmiObject -Class win32_networkadapter -Filter \"DeviceID = $($Entry.AdapterIndex)\"\n        \n        $Entry.Add('AdapterServiceName', $Adapter.ServiceName)\n        $Entry.Add('AdapterMacAddress', $Adapter.MACAddress)\n        $Entry.Add('AdapterType', $Adapter.AdapterType)\n        $Entry.Add('AdapterName', $Adapter.Name)\n        $Entry.Add('AdapterSpeed', $Adapter.Speed)\n        \n        Write-Output $Entry\n    }\n}\n\nfunction GetIpNetTable\n{\n    <#\n    .SYNOPSIS\n\n    Retreives the IPv4 to physical address mapping table.\n\n    .DESCRIPTION\n\n    The GetIpNetTable function enumerates the Address Resolution Protocol (ARP) entries for IPv4 on a local system from the IPv4 to physical address mapping table and returns this information in a MIB_IPNETTABLE structure.\n\n    on Windows Vista and later, the GetIpNetTable2 function can be used to retrieve the neighbor IP addresses for both IPv6 and IPv4.\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: MIB_IPNETROW (Struct), MIB_IPNET_TYPE (Enum)\n    Optional Dependencies: None\n    \n    (func iphlpapi GetIpNetTable ([Int32]) @(\n        [IntPtr],                 #_Out_   PMIB_IPNETTABLE pIpNetTable\n        [Int32].MakeByRefType(),  #_Inout_ PULONG          pdwSize\n        [bool]                    #_In_    BOOL            bOrder\n    ))\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa365956%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396\n\n    .EXAMPLE\n\n    GetIpNetTable\n\n    AdapterIndex PhysicalAddress   IpAddress          Type\n    ------------ ---------------   ---------          ----\n              14 00-50-56-C0-00-08 192.168.1.1      DYNAMIC\n              14 00-50-56-F8-64-30 192.168.1.2      DYNAMIC\n              14 00-0C-29-BB-51-6D 192.168.1.137    DYNAMIC\n              14 00-00-00-00-00-00 192.168.1.254    INVALID\n              14 FF-FF-FF-FF-FF-FF 192.168.1.255    STATIC\n              14 01-00-5E-00-00-16 224.0.0.22       STATIC\n              14 01-00-5E-00-00-FC 224.0.0.252      STATIC\n              14 01-00-5E-7F-FF-FA 239.255.255.250  STATIC\n              14 FF-FF-FF-FF-FF-FF 255.255.255.255  STATIC\n               1 00-00-00-00-00-00 224.0.0.22       STATIC\n               1 00-00-00-00-00-00 224.0.0.252      STATIC\n               1 00-00-00-00-00-00 239.255.255.250  STATIC\n              11 01-00-5E-00-00-16 224.0.0.22       STATIC\n              10 01-00-5E-00-00-16 224.0.0.22       STATIC\n    #>\n\n    $pThrowAway = [IntPtr]::Zero\n    $dwSize = [Int32]0\n\n    # Run the function once to get the size of the MIB_NETTABLE Structure\n    $SUCCESS = $iphlpapi::GetIpNetTable($pThrowAway, [ref]$dwSize, $false)\n    \n    # ERROR_INSUFFICIENT_BUFFER means that $dwSize now contains the size of the stucture\n    if($SUCCESS -eq 122)\n    {\n        $pIpNetTable = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($dwSize)\n        $SUCCESS = $iphlpapi::GetIpNetTable($pIpNetTable, [ref]$dwSize, $false)\n        \n        if($SUCCESS -eq 0)\n        {\n            $count = [System.Runtime.InteropServices.Marshal]::ReadInt32($pIpNetTable)\n\n            for($i = 0; $i -lt $count; $i++)\n            {\n                $CurrentPtr = [IntPtr]($pIpNetTable.ToInt64() + 4 + ($i * 24))\n                $IpNetRow = $CurrentPtr -as $MIB_IPNETROW\n    \n                [byte[]]$bAddress = $IpNetRow.bPhysAddr\n\n                $obj = @{\n                    AdapterIndex = $IpNetRow.dwIndex\n                    PhysicalAddress = [System.BitConverter]::ToString($bAddress).Replace('-',':')\n                    IpAddress = [string]([System.Net.IPAddress]::new($IpNetRow.dwAddr).IPAddressToString)\n                    Type = [string]($IpNetRow.dwType -as $MIB_IPNET_TYPE)\n                }\n\n                Write-Output $obj\n            }\n        }\n    }\n\n    [System.Runtime.InteropServices.Marshal]::FreeHGlobal($pIpNetTable)\n}\n\n#region PSReflect\nfunction New-InMemoryModule\n{\n<#\n.SYNOPSIS\n\nCreates an in-memory assembly and module\n\nAuthor: Matthew Graeber (@mattifestation)\nLicense: BSD 3-Clause\nRequired Dependencies: None\nOptional Dependencies: None\n \n.DESCRIPTION\n\nWhen defining custom enums, structs, and unmanaged functions, it is\nnecessary to associate to an assembly module. This helper function\ncreates an in-memory module that can be passed to the 'enum',\n'struct', and Add-Win32Type functions.\n\n.PARAMETER ModuleName\n\nSpecifies the desired name for the in-memory assembly and module. If\nModuleName is not provided, it will default to a GUID.\n\n.EXAMPLE\n\n$Module = New-InMemoryModule -ModuleName Win32\n#>\n\n    Param\n    (\n        [Parameter(Position = 0)]\n        [ValidateNotNullOrEmpty()]\n        [String]\n        $ModuleName = [Guid]::NewGuid().ToString()\n    )\n\n    $AppDomain = [Reflection.Assembly].Assembly.GetType('System.AppDomain').GetProperty('CurrentDomain').GetValue($null, @())\n    $LoadedAssemblies = $AppDomain.GetAssemblies()\n\n    foreach ($Assembly in $LoadedAssemblies) {\n        if ($Assembly.FullName -and ($Assembly.FullName.Split(',')[0] -eq $ModuleName)) {\n            return $Assembly\n        }\n    }\n\n    $DynAssembly = New-Object Reflection.AssemblyName($ModuleName)\n    $Domain = $AppDomain\n    $AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, 'Run')\n    $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule($ModuleName, $False)\n\n    return $ModuleBuilder\n}\n\n# A helper function used to reduce typing while defining function\n# prototypes for Add-Win32Type.\nfunction func\n{\n    Param\n    (\n        [Parameter(Position = 0, Mandatory = $True)]\n        [String]\n        $DllName,\n\n        [Parameter(Position = 1, Mandatory = $True)]\n        [string]\n        $FunctionName,\n\n        [Parameter(Position = 2, Mandatory = $True)]\n        [Type]\n        $ReturnType,\n\n        [Parameter(Position = 3)]\n        [Type[]]\n        $ParameterTypes,\n\n        [Parameter(Position = 4)]\n        [Runtime.InteropServices.CallingConvention]\n        $NativeCallingConvention,\n\n        [Parameter(Position = 5)]\n        [Runtime.InteropServices.CharSet]\n        $Charset,\n\n        [String]\n        $EntryPoint,\n\n        [Switch]\n        $SetLastError\n    )\n\n    $Properties = @{\n        DllName = $DllName\n        FunctionName = $FunctionName\n        ReturnType = $ReturnType\n    }\n\n    if ($ParameterTypes) { $Properties['ParameterTypes'] = $ParameterTypes }\n    if ($NativeCallingConvention) { $Properties['NativeCallingConvention'] = $NativeCallingConvention }\n    if ($Charset) { $Properties['Charset'] = $Charset }\n    if ($SetLastError) { $Properties['SetLastError'] = $SetLastError }\n    if ($EntryPoint) { $Properties['EntryPoint'] = $EntryPoint }\n\n    New-Object PSObject -Property $Properties\n}\n\nfunction Add-Win32Type\n{\n<#\n.SYNOPSIS\n\nCreates a .NET type for an unmanaged Win32 function.\n\nAuthor: Matthew Graeber (@mattifestation)\nLicense: BSD 3-Clause\nRequired Dependencies: None\nOptional Dependencies: func\n \n.DESCRIPTION\n\nAdd-Win32Type enables you to easily interact with unmanaged (i.e.\nWin32 unmanaged) functions in PowerShell. After providing\nAdd-Win32Type with a function signature, a .NET type is created\nusing reflection (i.e. csc.exe is never called like with Add-Type).\n\nThe 'func' helper function can be used to reduce typing when defining\nmultiple function definitions.\n\n.PARAMETER DllName\n\nThe name of the DLL.\n\n.PARAMETER FunctionName\n\nThe name of the target function.\n\n.PARAMETER EntryPoint\n\nThe DLL export function name. This argument should be specified if the\nspecified function name is different than the name of the exported\nfunction.\n\n.PARAMETER ReturnType\n\nThe return type of the function.\n\n.PARAMETER ParameterTypes\n\nThe function parameters.\n\n.PARAMETER NativeCallingConvention\n\nSpecifies the native calling convention of the function. Defaults to\nstdcall.\n\n.PARAMETER Charset\n\nIf you need to explicitly call an 'A' or 'W' Win32 function, you can\nspecify the character set.\n\n.PARAMETER SetLastError\n\nIndicates whether the callee calls the SetLastError Win32 API\nfunction before returning from the attributed method.\n\n.PARAMETER Module\n\nThe in-memory module that will host the functions. Use\nNew-InMemoryModule to define an in-memory module.\n\n.PARAMETER Namespace\n\nAn optional namespace to prepend to the type. Add-Win32Type defaults\nto a namespace consisting only of the name of the DLL.\n\n.EXAMPLE\n\n$Mod = New-InMemoryModule -ModuleName Win32\n\n$FunctionDefinitions = @(\n    (func kernel32 GetProcAddress ([IntPtr]) @([IntPtr], [String]) -Charset Ansi -SetLastError),\n    (func kernel32 GetModuleHandle ([Intptr]) @([String]) -SetLastError),\n    (func ntdll RtlGetCurrentPeb ([IntPtr]) @())\n)\n\n$Types = $FunctionDefinitions | Add-Win32Type -Module $Mod -Namespace 'Win32'\n$Kernel32 = $Types['kernel32']\n$Ntdll = $Types['ntdll']\n$Ntdll::RtlGetCurrentPeb()\n$ntdllbase = $Kernel32::GetModuleHandle('ntdll')\n$Kernel32::GetProcAddress($ntdllbase, 'RtlGetCurrentPeb')\n\n.NOTES\n\nInspired by Lee Holmes' Invoke-WindowsApi http://poshcode.org/2189\n\nWhen defining multiple function prototypes, it is ideal to provide\nAdd-Win32Type with an array of function signatures. That way, they\nare all incorporated into the same in-memory module.\n#>\n\n    [OutputType([Hashtable])]\n    Param(\n        [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)]\n        [String]\n        $DllName,\n\n        [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)]\n        [String]\n        $FunctionName,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [String]\n        $EntryPoint,\n\n        [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)]\n        [Type]\n        $ReturnType,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [Type[]]\n        $ParameterTypes,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [Runtime.InteropServices.CallingConvention]\n        $NativeCallingConvention = [Runtime.InteropServices.CallingConvention]::StdCall,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [Runtime.InteropServices.CharSet]\n        $Charset = [Runtime.InteropServices.CharSet]::Auto,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [Switch]\n        $SetLastError,\n\n        [Parameter(Mandatory = $True)]\n        [ValidateScript({($_ -is [Reflection.Emit.ModuleBuilder]) -or ($_ -is [Reflection.Assembly])})]\n        $Module,\n\n        [ValidateNotNull()]\n        [String]\n        $Namespace = ''\n    )\n\n    BEGIN\n    {\n        $TypeHash = @{}\n    }\n\n    PROCESS\n    {\n        if ($Module -is [Reflection.Assembly])\n        {\n            if ($Namespace)\n            {\n                $TypeHash[$DllName] = $Module.GetType(\"$Namespace.$DllName\")\n            }\n            else\n            {\n                $TypeHash[$DllName] = $Module.GetType($DllName)\n            }\n        }\n        else\n        {\n            # Define one type for each DLL\n            if (!$TypeHash.ContainsKey($DllName))\n            {\n                if ($Namespace)\n                {\n                    $TypeHash[$DllName] = $Module.DefineType(\"$Namespace.$DllName\", 'Public,BeforeFieldInit')\n                }\n                else\n                {\n                    $TypeHash[$DllName] = $Module.DefineType($DllName, 'Public,BeforeFieldInit')\n                }\n            }\n\n            $Method = $TypeHash[$DllName].DefineMethod(\n                $FunctionName,\n                'Public,Static,PinvokeImpl',\n                $ReturnType,\n                $ParameterTypes)\n\n            # Make each ByRef parameter an Out parameter\n            $i = 1\n            foreach($Parameter in $ParameterTypes)\n            {\n                if ($Parameter.IsByRef)\n                {\n                    [void] $Method.DefineParameter($i, 'Out', $null)\n                }\n\n                $i++\n            }\n\n            $DllImport = [Runtime.InteropServices.DllImportAttribute]\n            $SetLastErrorField = $DllImport.GetField('SetLastError')\n            $CallingConventionField = $DllImport.GetField('CallingConvention')\n            $CharsetField = $DllImport.GetField('CharSet')\n            $EntryPointField = $DllImport.GetField('EntryPoint')\n            if ($SetLastError) { $SLEValue = $True } else { $SLEValue = $False }\n\n            if ($PSBoundParameters['EntryPoint']) { $ExportedFuncName = $EntryPoint } else { $ExportedFuncName = $FunctionName }\n\n            # Equivalent to C# version of [DllImport(DllName)]\n            $Constructor = [Runtime.InteropServices.DllImportAttribute].GetConstructor([String])\n            $DllImportAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($Constructor,\n                $DllName, [Reflection.PropertyInfo[]] @(), [Object[]] @(),\n                [Reflection.FieldInfo[]] @($SetLastErrorField,\n                                            $CallingConventionField,\n                                            $CharsetField,\n                                            $EntryPointField),\n                [Object[]] @($SLEValue,\n                                ([Runtime.InteropServices.CallingConvention] $NativeCallingConvention),\n                                ([Runtime.InteropServices.CharSet] $Charset),\n                                $ExportedFuncName))\n\n            $Method.SetCustomAttribute($DllImportAttribute)\n        }\n    }\n\n    END\n    {\n        if ($Module -is [Reflection.Assembly])\n        {\n            return $TypeHash\n        }\n\n        $ReturnTypes = @{}\n\n        foreach ($Key in $TypeHash.Keys)\n        {\n            $Type = $TypeHash[$Key].CreateType()\n            \n            $ReturnTypes[$Key] = $Type\n        }\n\n        return $ReturnTypes\n    }\n}\n\nfunction psenum\n{\n<#\n.SYNOPSIS\n\nCreates an in-memory enumeration for use in your PowerShell session.\n\nAuthor: Matthew Graeber (@mattifestation)\nLicense: BSD 3-Clause\nRequired Dependencies: None\nOptional Dependencies: None\n \n.DESCRIPTION\n\nThe 'psenum' function facilitates the creation of enums entirely in\nmemory using as close to a \"C style\" as PowerShell will allow.\n\n.PARAMETER Module\n\nThe in-memory module that will host the enum. Use\nNew-InMemoryModule to define an in-memory module.\n\n.PARAMETER FullName\n\nThe fully-qualified name of the enum.\n\n.PARAMETER Type\n\nThe type of each enum element.\n\n.PARAMETER EnumElements\n\nA hashtable of enum elements.\n\n.PARAMETER Bitfield\n\nSpecifies that the enum should be treated as a bitfield.\n\n.EXAMPLE\n\n$Mod = New-InMemoryModule -ModuleName Win32\n\n$ImageSubsystem = psenum $Mod PE.IMAGE_SUBSYSTEM UInt16 @{\n    UNKNOWN =                  0\n    NATIVE =                   1 # Image doesn't require a subsystem.\n    WINDOWS_GUI =              2 # Image runs in the Windows GUI subsystem.\n    WINDOWS_CUI =              3 # Image runs in the Windows character subsystem.\n    OS2_CUI =                  5 # Image runs in the OS/2 character subsystem.\n    POSIX_CUI =                7 # Image runs in the Posix character subsystem.\n    NATIVE_WINDOWS =           8 # Image is a native Win9x driver.\n    WINDOWS_CE_GUI =           9 # Image runs in the Windows CE subsystem.\n    EFI_APPLICATION =          10\n    EFI_BOOT_SERVICE_DRIVER =  11\n    EFI_RUNTIME_DRIVER =       12\n    EFI_ROM =                  13\n    XBOX =                     14\n    WINDOWS_BOOT_APPLICATION = 16\n}\n\n.NOTES\n\nPowerShell purists may disagree with the naming of this function but\nagain, this was developed in such a way so as to emulate a \"C style\"\ndefinition as closely as possible. Sorry, I'm not going to name it\nNew-Enum. :P\n#>\n\n    [OutputType([Type])]\n    Param\n    (\n        [Parameter(Position = 0, Mandatory = $True)]\n        [ValidateScript({($_ -is [Reflection.Emit.ModuleBuilder]) -or ($_ -is [Reflection.Assembly])})]\n        $Module,\n\n        [Parameter(Position = 1, Mandatory = $True)]\n        [ValidateNotNullOrEmpty()]\n        [String]\n        $FullName,\n\n        [Parameter(Position = 2, Mandatory = $True)]\n        [Type]\n        $Type,\n\n        [Parameter(Position = 3, Mandatory = $True)]\n        [ValidateNotNullOrEmpty()]\n        [Hashtable]\n        $EnumElements,\n\n        [Switch]\n        $Bitfield\n    )\n\n    if ($Module -is [Reflection.Assembly])\n    {\n        return ($Module.GetType($FullName))\n    }\n\n    $EnumType = $Type -as [Type]\n\n    $EnumBuilder = $Module.DefineEnum($FullName, 'Public', $EnumType)\n\n    if ($Bitfield)\n    {\n        $FlagsConstructor = [FlagsAttribute].GetConstructor(@())\n        $FlagsCustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($FlagsConstructor, @())\n        $EnumBuilder.SetCustomAttribute($FlagsCustomAttribute)\n    }\n\n    foreach ($Key in $EnumElements.Keys)\n    {\n        # Apply the specified enum type to each element\n        $null = $EnumBuilder.DefineLiteral($Key, $EnumElements[$Key] -as $EnumType)\n    }\n\n    $EnumBuilder.CreateType()\n}\n\n# A helper function used to reduce typing while defining struct\n# fields.\nfunction field\n{\n    Param\n    (\n        [Parameter(Position = 0, Mandatory = $True)]\n        [UInt16]\n        $Position,\n        \n        [Parameter(Position = 1, Mandatory = $True)]\n        [Type]\n        $Type,\n        \n        [Parameter(Position = 2)]\n        [UInt16]\n        $Offset,\n        \n        [Object[]]\n        $MarshalAs\n    )\n\n    @{\n        Position = $Position\n        Type = $Type -as [Type]\n        Offset = $Offset\n        MarshalAs = $MarshalAs\n    }\n}\n\nfunction struct\n{\n<#\n.SYNOPSIS\n\nCreates an in-memory struct for use in your PowerShell session.\n\nAuthor: Matthew Graeber (@mattifestation)\nLicense: BSD 3-Clause\nRequired Dependencies: None\nOptional Dependencies: field\n \n.DESCRIPTION\n\nThe 'struct' function facilitates the creation of structs entirely in\nmemory using as close to a \"C style\" as PowerShell will allow. Struct\nfields are specified using a hashtable where each field of the struct\nis comprosed of the order in which it should be defined, its .NET\ntype, and optionally, its offset and special marshaling attributes.\n\nOne of the features of 'struct' is that after your struct is defined,\nit will come with a built-in GetSize method as well as an explicit\nconverter so that you can easily cast an IntPtr to the struct without\nrelying upon calling SizeOf and/or PtrToStructure in the Marshal\nclass.\n\n.PARAMETER Module\n\nThe in-memory module that will host the struct. Use\nNew-InMemoryModule to define an in-memory module.\n\n.PARAMETER FullName\n\nThe fully-qualified name of the struct.\n\n.PARAMETER StructFields\n\nA hashtable of fields. Use the 'field' helper function to ease\ndefining each field.\n\n.PARAMETER PackingSize\n\nSpecifies the memory alignment of fields.\n\n.PARAMETER ExplicitLayout\n\nIndicates that an explicit offset for each field will be specified.\n\n.EXAMPLE\n\n$Mod = New-InMemoryModule -ModuleName Win32\n\n$ImageDosSignature = psenum $Mod PE.IMAGE_DOS_SIGNATURE UInt16 @{\n    DOS_SIGNATURE =    0x5A4D\n    OS2_SIGNATURE =    0x454E\n    OS2_SIGNATURE_LE = 0x454C\n    VXD_SIGNATURE =    0x454C\n}\n\n$ImageDosHeader = struct $Mod PE.IMAGE_DOS_HEADER @{\n    e_magic =    field 0 $ImageDosSignature\n    e_cblp =     field 1 UInt16\n    e_cp =       field 2 UInt16\n    e_crlc =     field 3 UInt16\n    e_cparhdr =  field 4 UInt16\n    e_minalloc = field 5 UInt16\n    e_maxalloc = field 6 UInt16\n    e_ss =       field 7 UInt16\n    e_sp =       field 8 UInt16\n    e_csum =     field 9 UInt16\n    e_ip =       field 10 UInt16\n    e_cs =       field 11 UInt16\n    e_lfarlc =   field 12 UInt16\n    e_ovno =     field 13 UInt16\n    e_res =      field 14 UInt16[] -MarshalAs @('ByValArray', 4)\n    e_oemid =    field 15 UInt16\n    e_oeminfo =  field 16 UInt16\n    e_res2 =     field 17 UInt16[] -MarshalAs @('ByValArray', 10)\n    e_lfanew =   field 18 Int32\n}\n\n# Example of using an explicit layout in order to create a union.\n$TestUnion = struct $Mod TestUnion @{\n    field1 = field 0 UInt32 0\n    field2 = field 1 IntPtr 0\n} -ExplicitLayout\n\n.NOTES\n\nPowerShell purists may disagree with the naming of this function but\nagain, this was developed in such a way so as to emulate a \"C style\"\ndefinition as closely as possible. Sorry, I'm not going to name it\nNew-Struct. :P\n#>\n\n    [OutputType([Type])]\n    Param\n    (\n        [Parameter(Position = 1, Mandatory = $True)]\n        [ValidateScript({($_ -is [Reflection.Emit.ModuleBuilder]) -or ($_ -is [Reflection.Assembly])})]\n        $Module,\n\n        [Parameter(Position = 2, Mandatory = $True)]\n        [ValidateNotNullOrEmpty()]\n        [String]\n        $FullName,\n\n        [Parameter(Position = 3, Mandatory = $True)]\n        [ValidateNotNullOrEmpty()]\n        [Hashtable]\n        $StructFields,\n\n        [Reflection.Emit.PackingSize]\n        $PackingSize = [Reflection.Emit.PackingSize]::Unspecified,\n\n        [Switch]\n        $ExplicitLayout\n    )\n\n    if ($Module -is [Reflection.Assembly])\n    {\n        return ($Module.GetType($FullName))\n    }\n\n    [Reflection.TypeAttributes] $StructAttributes = 'AnsiClass,\n        Class,\n        Public,\n        Sealed,\n        BeforeFieldInit'\n\n    if ($ExplicitLayout)\n    {\n        $StructAttributes = $StructAttributes -bor [Reflection.TypeAttributes]::ExplicitLayout\n    }\n    else\n    {\n        $StructAttributes = $StructAttributes -bor [Reflection.TypeAttributes]::SequentialLayout\n    }\n\n    $StructBuilder = $Module.DefineType($FullName, $StructAttributes, [ValueType], $PackingSize)\n    $ConstructorInfo = [Runtime.InteropServices.MarshalAsAttribute].GetConstructors()[0]\n    $SizeConst = @([Runtime.InteropServices.MarshalAsAttribute].GetField('SizeConst'))\n\n    $Fields = New-Object Hashtable[]($StructFields.Count)\n\n    # Sort each field according to the orders specified\n    # Unfortunately, PSv2 doesn't have the luxury of the\n    # hashtable [Ordered] accelerator.\n    foreach ($Field in $StructFields.Keys)\n    {\n        $Index = $StructFields[$Field]['Position']\n        $Fields[$Index] = @{FieldName = $Field; Properties = $StructFields[$Field]}\n    }\n\n    foreach ($Field in $Fields)\n    {\n        $FieldName = $Field['FieldName']\n        $FieldProp = $Field['Properties']\n\n        $Offset = $FieldProp['Offset']\n        $Type = $FieldProp['Type']\n        $MarshalAs = $FieldProp['MarshalAs']\n\n        $NewField = $StructBuilder.DefineField($FieldName, $Type, 'Public')\n\n        if ($MarshalAs)\n        {\n            $UnmanagedType = $MarshalAs[0] -as ([Runtime.InteropServices.UnmanagedType])\n            if ($MarshalAs[1])\n            {\n                $Size = $MarshalAs[1]\n                $AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($ConstructorInfo,\n                    $UnmanagedType, $SizeConst, @($Size))\n            }\n            else\n            {\n                $AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($ConstructorInfo, [Object[]] @($UnmanagedType))\n            }\n            \n            $NewField.SetCustomAttribute($AttribBuilder)\n        }\n\n        if ($ExplicitLayout) { $NewField.SetOffset($Offset) }\n    }\n\n    # Make the struct aware of its own size.\n    # No more having to call [Runtime.InteropServices.Marshal]::SizeOf!\n    $SizeMethod = $StructBuilder.DefineMethod('GetSize',\n        'Public, Static',\n        [Int],\n        [Type[]] @())\n    $ILGenerator = $SizeMethod.GetILGenerator()\n    # Thanks for the help, Jason Shirk!\n    $ILGenerator.Emit([Reflection.Emit.OpCodes]::Ldtoken, $StructBuilder)\n    $ILGenerator.Emit([Reflection.Emit.OpCodes]::Call,\n        [Type].GetMethod('GetTypeFromHandle'))\n    $ILGenerator.Emit([Reflection.Emit.OpCodes]::Call,\n        [Runtime.InteropServices.Marshal].GetMethod('SizeOf', [Type[]] @([Type])))\n    $ILGenerator.Emit([Reflection.Emit.OpCodes]::Ret)\n\n    # Allow for explicit casting from an IntPtr\n    # No more having to call [Runtime.InteropServices.Marshal]::PtrToStructure!\n    $ImplicitConverter = $StructBuilder.DefineMethod('op_Implicit',\n        'PrivateScope, Public, Static, HideBySig, SpecialName',\n        $StructBuilder,\n        [Type[]] @([IntPtr]))\n    $ILGenerator2 = $ImplicitConverter.GetILGenerator()\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Nop)\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ldarg_0)\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ldtoken, $StructBuilder)\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Call,\n        [Type].GetMethod('GetTypeFromHandle'))\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Call,\n        [Runtime.InteropServices.Marshal].GetMethod('PtrToStructure', [Type[]] @([IntPtr], [Type])))\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Unbox_Any, $StructBuilder)\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ret)\n\n    $StructBuilder.CreateType()\n}\n#endregion PSReflect\n\n#region PSReflect Definitions\n$mod = New-InMemoryModule -ModuleName ArpCache\n\n$MIB_IPNET_TYPE = psenum $mod MIB_IPNET_TYPE UInt32 @{\n    OTHER   = 1\n    INVALID = 2\n    DYNAMIC = 3\n    STATIC  = 4\n}\n\n$MIB_IPNETROW = struct $mod MIB_IPNETROW @{\n    dwIndex = field 0 UInt32\n    dwPhysAddrLen = field 1 UInt32\n    bPhysAddr = field 2 byte[] -MarshalAs @('ByValArray', 6)\n    dwAddr = field 3 UInt32\n    dwType = field 4 UInt32\n}\n\n$FunctionDefinitions = @(\n    (func iphlpapi GetIpNetTable ([Int32]) @(\n        [IntPtr],                 #_Out_   PMIB_IPNETTABLE pIpNetTable\n        [Int32].MakeByRefType(),  #_Inout_ PULONG          pdwSize\n        [bool]                    #_In_    BOOL            bOrder\n    ))\n)\n\n$Types = $FunctionDefinitions | Add-Win32Type -Module $mod -Namespace ArpCache\n$Iphlpapi = $Types['iphlpapi']\n#endregion PSReflect Definitions\n\nStart-AceScript -Uri https://10.182.18.200 -SweepId $args[0] -ScanId ([Guid]::NewGuid()) -RoutingKey siem -Thumbprint 8D1DB3B7B85B6F9E9DE87B291DF66692A10240AE"
  },
  {
    "path": "ACE-Management/PS-ACE/Scripts/ACE_Get-Atom.ps1",
    "content": "﻿function Start-AceScript\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $SweepId,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $ScanId,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $RoutingKey,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Thumbprint\n    )\n\n    $HostFQDN = Get-WmiObject Win32_ComputerSystem -Property 'Name','Domain' | ForEach-Object {\"$($_.Name).$($_.Domain)\"}\n    $ResultDate = (Get-Date).ToString(\"yyyyMMddThhmmssmsmsZ\")\n\n    $dataList = New-Object -TypeName System.Collections.Generic.List['string']\n\n    foreach($o in (Get-Atom))\n    {\n        $o.Add('ComputerName', $HostFQDN)\n        $o.Add('ScanType', 'Atom')\n        $o.Add('SweepId', $SweepId)\n        $o.Add('ScanId', $ScanId)\n        $o.Add('ResultDate', $ResultDate)\n\n        $message = ConvertTo-JsonV2 -InputObject $o\n        $dataList.Add($message)\n    }\n\n    $props = @{\n        ComputerName = $HostFQDN\n        ScanType     = 'Atom'\n        RoutingKey   = $RoutingKey\n        ResultDate   = $ResultDate\n        ScanId       = $ScanId\n        Data         = $dataList.ToArray()\n    }\n\n    $body = (ConvertTo-JsonV2 -InputObject $props)\n    \n    Write-Output $body\n    \n    #Invoke-AceWebRequest -Thumbprint $Thumbprint -Uri \"$($Uri)/ace/result/$($SweepId)\" -Body $body\n}\n\nfunction ConvertTo-JsonV2 \n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        $InputObject\n    )\n\n    Begin \n    {\n        $null = [System.Reflection.Assembly]::LoadWithPartialName(\"System.Web.Extensions\")\n        $Serializer = New-Object System.Web.Script.Serialization.JavaScriptSerializer\n    }\n\n    Process \n    {\n        try \n        {\n            $Serializer.Serialize($InputObject)\n        } \n        catch \n        {\n            Write-Error $_\n        }    \n    }\n}\n\nfunction Invoke-AceWebRequest\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Thumbprint,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Body\n    )\n\n    [Net.ServicePointManager]::ServerCertificateValidationCallback = {\n        $Thumbprint = $Thumbprint\n        $certificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]$args[1]\n    \n        if ($certificate -eq $null)\n        {\n            $Host.UI.WriteErrorLine(\"Null certificate.\")\n            return $true\n        }\n    \n        if ($certificate.Thumbprint -eq $Thumbprint)\n        {\n            return $true\n        }\n        else\n        {\n            $Host.UI.WriteErrorLine(\"Thumbprint mismatch. Certificate thumbprint $($certificate.Thumbprint)\")\n        }\n    \n        return $false\n    }\n\n    try\n    {\n        Write-Host \"URI: $($Uri)\"\n\n        # Create web request\n        $WebRequest = [Net.WebRequest]::Create($uri)\n        $WebRequest.Method = 'Post'\n        $WebRequest.ContentType = 'application/json'\n        $WebRequest.Headers.Add('X-API-Version:1.0')\n\n        $byteArray = [System.Text.Encoding]::UTF8.GetBytes($Body)\n        $Webrequest.ContentLength = $byteArray.Length\n        \n        $dataStream = $Webrequest.GetRequestStream()            \n        $dataStream.Write($byteArray, 0, $byteArray.Length)\n        $dataStream.Close()\n\n        # Get response stream\n        $ResponseStream = $Webrequest.GetResponse().GetResponseStream()\n    \n        # Create a stream reader and read the stream returning the string value.\n        $StreamReader = New-Object System.IO.StreamReader -ArgumentList $ResponseStream\n        $StreamReader.ReadToEnd()\n    }\n    catch\n    {\n        Write-Error \"Failed: $($_.exception.innerexception.message)\"\n    }\n}\n\nfunction Get-Atom\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter()]\n        [UInt16]\n        $AtomIndex\n    )\n\n    if($PSBoundParameters.ContainsKey('AtomIndex'))\n    {\n        GlobalGetAtomName -AtomIndex $AtomIndex\n    }\n    else\n    {\n        $atomList = New-Object -TypeName System.Collections.Generic.List['string']\n\n        for($i = 0xC000; $i -lt [UInt16]::MaxValue; $i++)\n        {\n            try\n            {\n                $atomname = GlobalGetAtomName -AtomIndex $i -ErrorAction Stop\n            \n                $props = @{\n                    Index = $i\n                    Name = $atomname.ToString()\n                }\n\n                Write-Output $props \n            }\n            catch\n            {\n\n            }\n        }\n    }\n}\n\n#region PSReflect\nfunction New-InMemoryModule\n{\n<#\n.SYNOPSIS\n\nCreates an in-memory assembly and module\n\nAuthor: Matthew Graeber (@mattifestation)\nLicense: BSD 3-Clause\nRequired Dependencies: None\nOptional Dependencies: None\n \n.DESCRIPTION\n\nWhen defining custom enums, structs, and unmanaged functions, it is\nnecessary to associate to an assembly module. This helper function\ncreates an in-memory module that can be passed to the 'enum',\n'struct', and Add-Win32Type functions.\n\n.PARAMETER ModuleName\n\nSpecifies the desired name for the in-memory assembly and module. If\nModuleName is not provided, it will default to a GUID.\n\n.EXAMPLE\n\n$Module = New-InMemoryModule -ModuleName Win32\n#>\n\n    Param\n    (\n        [Parameter(Position = 0)]\n        [ValidateNotNullOrEmpty()]\n        [String]\n        $ModuleName = [Guid]::NewGuid().ToString()\n    )\n\n    $AppDomain = [Reflection.Assembly].Assembly.GetType('System.AppDomain').GetProperty('CurrentDomain').GetValue($null, @())\n    $LoadedAssemblies = $AppDomain.GetAssemblies()\n\n    foreach ($Assembly in $LoadedAssemblies) {\n        if ($Assembly.FullName -and ($Assembly.FullName.Split(',')[0] -eq $ModuleName)) {\n            return $Assembly\n        }\n    }\n\n    $DynAssembly = New-Object Reflection.AssemblyName($ModuleName)\n    $Domain = $AppDomain\n    $AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, 'Run')\n    $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule($ModuleName, $False)\n\n    return $ModuleBuilder\n}\n\n# A helper function used to reduce typing while defining function\n# prototypes for Add-Win32Type.\nfunction func\n{\n    Param\n    (\n        [Parameter(Position = 0, Mandatory = $True)]\n        [String]\n        $DllName,\n\n        [Parameter(Position = 1, Mandatory = $True)]\n        [string]\n        $FunctionName,\n\n        [Parameter(Position = 2, Mandatory = $True)]\n        [Type]\n        $ReturnType,\n\n        [Parameter(Position = 3)]\n        [Type[]]\n        $ParameterTypes,\n\n        [Parameter(Position = 4)]\n        [Runtime.InteropServices.CallingConvention]\n        $NativeCallingConvention,\n\n        [Parameter(Position = 5)]\n        [Runtime.InteropServices.CharSet]\n        $Charset,\n\n        [String]\n        $EntryPoint,\n\n        [Switch]\n        $SetLastError\n    )\n\n    $Properties = @{\n        DllName = $DllName\n        FunctionName = $FunctionName\n        ReturnType = $ReturnType\n    }\n\n    if ($ParameterTypes) { $Properties['ParameterTypes'] = $ParameterTypes }\n    if ($NativeCallingConvention) { $Properties['NativeCallingConvention'] = $NativeCallingConvention }\n    if ($Charset) { $Properties['Charset'] = $Charset }\n    if ($SetLastError) { $Properties['SetLastError'] = $SetLastError }\n    if ($EntryPoint) { $Properties['EntryPoint'] = $EntryPoint }\n\n    New-Object PSObject -Property $Properties\n}\n\nfunction Add-Win32Type\n{\n<#\n.SYNOPSIS\n\nCreates a .NET type for an unmanaged Win32 function.\n\nAuthor: Matthew Graeber (@mattifestation)\nLicense: BSD 3-Clause\nRequired Dependencies: None\nOptional Dependencies: func\n \n.DESCRIPTION\n\nAdd-Win32Type enables you to easily interact with unmanaged (i.e.\nWin32 unmanaged) functions in PowerShell. After providing\nAdd-Win32Type with a function signature, a .NET type is created\nusing reflection (i.e. csc.exe is never called like with Add-Type).\n\nThe 'func' helper function can be used to reduce typing when defining\nmultiple function definitions.\n\n.PARAMETER DllName\n\nThe name of the DLL.\n\n.PARAMETER FunctionName\n\nThe name of the target function.\n\n.PARAMETER EntryPoint\n\nThe DLL export function name. This argument should be specified if the\nspecified function name is different than the name of the exported\nfunction.\n\n.PARAMETER ReturnType\n\nThe return type of the function.\n\n.PARAMETER ParameterTypes\n\nThe function parameters.\n\n.PARAMETER NativeCallingConvention\n\nSpecifies the native calling convention of the function. Defaults to\nstdcall.\n\n.PARAMETER Charset\n\nIf you need to explicitly call an 'A' or 'W' Win32 function, you can\nspecify the character set.\n\n.PARAMETER SetLastError\n\nIndicates whether the callee calls the SetLastError Win32 API\nfunction before returning from the attributed method.\n\n.PARAMETER Module\n\nThe in-memory module that will host the functions. Use\nNew-InMemoryModule to define an in-memory module.\n\n.PARAMETER Namespace\n\nAn optional namespace to prepend to the type. Add-Win32Type defaults\nto a namespace consisting only of the name of the DLL.\n\n.EXAMPLE\n\n$Mod = New-InMemoryModule -ModuleName Win32\n\n$FunctionDefinitions = @(\n    (func kernel32 GetProcAddress ([IntPtr]) @([IntPtr], [String]) -Charset Ansi -SetLastError),\n    (func kernel32 GetModuleHandle ([Intptr]) @([String]) -SetLastError),\n    (func ntdll RtlGetCurrentPeb ([IntPtr]) @())\n)\n\n$Types = $FunctionDefinitions | Add-Win32Type -Module $Mod -Namespace 'Win32'\n$Kernel32 = $Types['kernel32']\n$Ntdll = $Types['ntdll']\n$Ntdll::RtlGetCurrentPeb()\n$ntdllbase = $Kernel32::GetModuleHandle('ntdll')\n$Kernel32::GetProcAddress($ntdllbase, 'RtlGetCurrentPeb')\n\n.NOTES\n\nInspired by Lee Holmes' Invoke-WindowsApi http://poshcode.org/2189\n\nWhen defining multiple function prototypes, it is ideal to provide\nAdd-Win32Type with an array of function signatures. That way, they\nare all incorporated into the same in-memory module.\n#>\n\n    [OutputType([Hashtable])]\n    Param(\n        [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)]\n        [String]\n        $DllName,\n\n        [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)]\n        [String]\n        $FunctionName,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [String]\n        $EntryPoint,\n\n        [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)]\n        [Type]\n        $ReturnType,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [Type[]]\n        $ParameterTypes,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [Runtime.InteropServices.CallingConvention]\n        $NativeCallingConvention = [Runtime.InteropServices.CallingConvention]::StdCall,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [Runtime.InteropServices.CharSet]\n        $Charset = [Runtime.InteropServices.CharSet]::Auto,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [Switch]\n        $SetLastError,\n\n        [Parameter(Mandatory = $True)]\n        [ValidateScript({($_ -is [Reflection.Emit.ModuleBuilder]) -or ($_ -is [Reflection.Assembly])})]\n        $Module,\n\n        [ValidateNotNull()]\n        [String]\n        $Namespace = ''\n    )\n\n    BEGIN\n    {\n        $TypeHash = @{}\n    }\n\n    PROCESS\n    {\n        if ($Module -is [Reflection.Assembly])\n        {\n            if ($Namespace)\n            {\n                $TypeHash[$DllName] = $Module.GetType(\"$Namespace.$DllName\")\n            }\n            else\n            {\n                $TypeHash[$DllName] = $Module.GetType($DllName)\n            }\n        }\n        else\n        {\n            # Define one type for each DLL\n            if (!$TypeHash.ContainsKey($DllName))\n            {\n                if ($Namespace)\n                {\n                    $TypeHash[$DllName] = $Module.DefineType(\"$Namespace.$DllName\", 'Public,BeforeFieldInit')\n                }\n                else\n                {\n                    $TypeHash[$DllName] = $Module.DefineType($DllName, 'Public,BeforeFieldInit')\n                }\n            }\n\n            $Method = $TypeHash[$DllName].DefineMethod(\n                $FunctionName,\n                'Public,Static,PinvokeImpl',\n                $ReturnType,\n                $ParameterTypes)\n\n            # Make each ByRef parameter an Out parameter\n            $i = 1\n            foreach($Parameter in $ParameterTypes)\n            {\n                if ($Parameter.IsByRef)\n                {\n                    [void] $Method.DefineParameter($i, 'Out', $null)\n                }\n\n                $i++\n            }\n\n            $DllImport = [Runtime.InteropServices.DllImportAttribute]\n            $SetLastErrorField = $DllImport.GetField('SetLastError')\n            $CallingConventionField = $DllImport.GetField('CallingConvention')\n            $CharsetField = $DllImport.GetField('CharSet')\n            $EntryPointField = $DllImport.GetField('EntryPoint')\n            if ($SetLastError) { $SLEValue = $True } else { $SLEValue = $False }\n\n            if ($PSBoundParameters['EntryPoint']) { $ExportedFuncName = $EntryPoint } else { $ExportedFuncName = $FunctionName }\n\n            # Equivalent to C# version of [DllImport(DllName)]\n            $Constructor = [Runtime.InteropServices.DllImportAttribute].GetConstructor([String])\n            $DllImportAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($Constructor,\n                $DllName, [Reflection.PropertyInfo[]] @(), [Object[]] @(),\n                [Reflection.FieldInfo[]] @($SetLastErrorField,\n                                            $CallingConventionField,\n                                            $CharsetField,\n                                            $EntryPointField),\n                [Object[]] @($SLEValue,\n                                ([Runtime.InteropServices.CallingConvention] $NativeCallingConvention),\n                                ([Runtime.InteropServices.CharSet] $Charset),\n                                $ExportedFuncName))\n\n            $Method.SetCustomAttribute($DllImportAttribute)\n        }\n    }\n\n    END\n    {\n        if ($Module -is [Reflection.Assembly])\n        {\n            return $TypeHash\n        }\n\n        $ReturnTypes = @{}\n\n        foreach ($Key in $TypeHash.Keys)\n        {\n            $Type = $TypeHash[$Key].CreateType()\n            \n            $ReturnTypes[$Key] = $Type\n        }\n\n        return $ReturnTypes\n    }\n}\n\nfunction psenum\n{\n<#\n.SYNOPSIS\n\nCreates an in-memory enumeration for use in your PowerShell session.\n\nAuthor: Matthew Graeber (@mattifestation)\nLicense: BSD 3-Clause\nRequired Dependencies: None\nOptional Dependencies: None\n \n.DESCRIPTION\n\nThe 'psenum' function facilitates the creation of enums entirely in\nmemory using as close to a \"C style\" as PowerShell will allow.\n\n.PARAMETER Module\n\nThe in-memory module that will host the enum. Use\nNew-InMemoryModule to define an in-memory module.\n\n.PARAMETER FullName\n\nThe fully-qualified name of the enum.\n\n.PARAMETER Type\n\nThe type of each enum element.\n\n.PARAMETER EnumElements\n\nA hashtable of enum elements.\n\n.PARAMETER Bitfield\n\nSpecifies that the enum should be treated as a bitfield.\n\n.EXAMPLE\n\n$Mod = New-InMemoryModule -ModuleName Win32\n\n$ImageSubsystem = psenum $Mod PE.IMAGE_SUBSYSTEM UInt16 @{\n    UNKNOWN =                  0\n    NATIVE =                   1 # Image doesn't require a subsystem.\n    WINDOWS_GUI =              2 # Image runs in the Windows GUI subsystem.\n    WINDOWS_CUI =              3 # Image runs in the Windows character subsystem.\n    OS2_CUI =                  5 # Image runs in the OS/2 character subsystem.\n    POSIX_CUI =                7 # Image runs in the Posix character subsystem.\n    NATIVE_WINDOWS =           8 # Image is a native Win9x driver.\n    WINDOWS_CE_GUI =           9 # Image runs in the Windows CE subsystem.\n    EFI_APPLICATION =          10\n    EFI_BOOT_SERVICE_DRIVER =  11\n    EFI_RUNTIME_DRIVER =       12\n    EFI_ROM =                  13\n    XBOX =                     14\n    WINDOWS_BOOT_APPLICATION = 16\n}\n\n.NOTES\n\nPowerShell purists may disagree with the naming of this function but\nagain, this was developed in such a way so as to emulate a \"C style\"\ndefinition as closely as possible. Sorry, I'm not going to name it\nNew-Enum. :P\n#>\n\n    [OutputType([Type])]\n    Param\n    (\n        [Parameter(Position = 0, Mandatory = $True)]\n        [ValidateScript({($_ -is [Reflection.Emit.ModuleBuilder]) -or ($_ -is [Reflection.Assembly])})]\n        $Module,\n\n        [Parameter(Position = 1, Mandatory = $True)]\n        [ValidateNotNullOrEmpty()]\n        [String]\n        $FullName,\n\n        [Parameter(Position = 2, Mandatory = $True)]\n        [Type]\n        $Type,\n\n        [Parameter(Position = 3, Mandatory = $True)]\n        [ValidateNotNullOrEmpty()]\n        [Hashtable]\n        $EnumElements,\n\n        [Switch]\n        $Bitfield\n    )\n\n    if ($Module -is [Reflection.Assembly])\n    {\n        return ($Module.GetType($FullName))\n    }\n\n    $EnumType = $Type -as [Type]\n\n    $EnumBuilder = $Module.DefineEnum($FullName, 'Public', $EnumType)\n\n    if ($Bitfield)\n    {\n        $FlagsConstructor = [FlagsAttribute].GetConstructor(@())\n        $FlagsCustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($FlagsConstructor, @())\n        $EnumBuilder.SetCustomAttribute($FlagsCustomAttribute)\n    }\n\n    foreach ($Key in $EnumElements.Keys)\n    {\n        # Apply the specified enum type to each element\n        $null = $EnumBuilder.DefineLiteral($Key, $EnumElements[$Key] -as $EnumType)\n    }\n\n    $EnumBuilder.CreateType()\n}\n\n# A helper function used to reduce typing while defining struct\n# fields.\nfunction field\n{\n    Param\n    (\n        [Parameter(Position = 0, Mandatory = $True)]\n        [UInt16]\n        $Position,\n        \n        [Parameter(Position = 1, Mandatory = $True)]\n        [Type]\n        $Type,\n        \n        [Parameter(Position = 2)]\n        [UInt16]\n        $Offset,\n        \n        [Object[]]\n        $MarshalAs\n    )\n\n    @{\n        Position = $Position\n        Type = $Type -as [Type]\n        Offset = $Offset\n        MarshalAs = $MarshalAs\n    }\n}\n\nfunction struct\n{\n<#\n.SYNOPSIS\n\nCreates an in-memory struct for use in your PowerShell session.\n\nAuthor: Matthew Graeber (@mattifestation)\nLicense: BSD 3-Clause\nRequired Dependencies: None\nOptional Dependencies: field\n \n.DESCRIPTION\n\nThe 'struct' function facilitates the creation of structs entirely in\nmemory using as close to a \"C style\" as PowerShell will allow. Struct\nfields are specified using a hashtable where each field of the struct\nis comprosed of the order in which it should be defined, its .NET\ntype, and optionally, its offset and special marshaling attributes.\n\nOne of the features of 'struct' is that after your struct is defined,\nit will come with a built-in GetSize method as well as an explicit\nconverter so that you can easily cast an IntPtr to the struct without\nrelying upon calling SizeOf and/or PtrToStructure in the Marshal\nclass.\n\n.PARAMETER Module\n\nThe in-memory module that will host the struct. Use\nNew-InMemoryModule to define an in-memory module.\n\n.PARAMETER FullName\n\nThe fully-qualified name of the struct.\n\n.PARAMETER StructFields\n\nA hashtable of fields. Use the 'field' helper function to ease\ndefining each field.\n\n.PARAMETER PackingSize\n\nSpecifies the memory alignment of fields.\n\n.PARAMETER ExplicitLayout\n\nIndicates that an explicit offset for each field will be specified.\n\n.EXAMPLE\n\n$Mod = New-InMemoryModule -ModuleName Win32\n\n$ImageDosSignature = psenum $Mod PE.IMAGE_DOS_SIGNATURE UInt16 @{\n    DOS_SIGNATURE =    0x5A4D\n    OS2_SIGNATURE =    0x454E\n    OS2_SIGNATURE_LE = 0x454C\n    VXD_SIGNATURE =    0x454C\n}\n\n$ImageDosHeader = struct $Mod PE.IMAGE_DOS_HEADER @{\n    e_magic =    field 0 $ImageDosSignature\n    e_cblp =     field 1 UInt16\n    e_cp =       field 2 UInt16\n    e_crlc =     field 3 UInt16\n    e_cparhdr =  field 4 UInt16\n    e_minalloc = field 5 UInt16\n    e_maxalloc = field 6 UInt16\n    e_ss =       field 7 UInt16\n    e_sp =       field 8 UInt16\n    e_csum =     field 9 UInt16\n    e_ip =       field 10 UInt16\n    e_cs =       field 11 UInt16\n    e_lfarlc =   field 12 UInt16\n    e_ovno =     field 13 UInt16\n    e_res =      field 14 UInt16[] -MarshalAs @('ByValArray', 4)\n    e_oemid =    field 15 UInt16\n    e_oeminfo =  field 16 UInt16\n    e_res2 =     field 17 UInt16[] -MarshalAs @('ByValArray', 10)\n    e_lfanew =   field 18 Int32\n}\n\n# Example of using an explicit layout in order to create a union.\n$TestUnion = struct $Mod TestUnion @{\n    field1 = field 0 UInt32 0\n    field2 = field 1 IntPtr 0\n} -ExplicitLayout\n\n.NOTES\n\nPowerShell purists may disagree with the naming of this function but\nagain, this was developed in such a way so as to emulate a \"C style\"\ndefinition as closely as possible. Sorry, I'm not going to name it\nNew-Struct. :P\n#>\n\n    [OutputType([Type])]\n    Param\n    (\n        [Parameter(Position = 1, Mandatory = $True)]\n        [ValidateScript({($_ -is [Reflection.Emit.ModuleBuilder]) -or ($_ -is [Reflection.Assembly])})]\n        $Module,\n\n        [Parameter(Position = 2, Mandatory = $True)]\n        [ValidateNotNullOrEmpty()]\n        [String]\n        $FullName,\n\n        [Parameter(Position = 3, Mandatory = $True)]\n        [ValidateNotNullOrEmpty()]\n        [Hashtable]\n        $StructFields,\n\n        [Reflection.Emit.PackingSize]\n        $PackingSize = [Reflection.Emit.PackingSize]::Unspecified,\n\n        [Switch]\n        $ExplicitLayout\n    )\n\n    if ($Module -is [Reflection.Assembly])\n    {\n        return ($Module.GetType($FullName))\n    }\n\n    [Reflection.TypeAttributes] $StructAttributes = 'AnsiClass,\n        Class,\n        Public,\n        Sealed,\n        BeforeFieldInit'\n\n    if ($ExplicitLayout)\n    {\n        $StructAttributes = $StructAttributes -bor [Reflection.TypeAttributes]::ExplicitLayout\n    }\n    else\n    {\n        $StructAttributes = $StructAttributes -bor [Reflection.TypeAttributes]::SequentialLayout\n    }\n\n    $StructBuilder = $Module.DefineType($FullName, $StructAttributes, [ValueType], $PackingSize)\n    $ConstructorInfo = [Runtime.InteropServices.MarshalAsAttribute].GetConstructors()[0]\n    $SizeConst = @([Runtime.InteropServices.MarshalAsAttribute].GetField('SizeConst'))\n\n    $Fields = New-Object Hashtable[]($StructFields.Count)\n\n    # Sort each field according to the orders specified\n    # Unfortunately, PSv2 doesn't have the luxury of the\n    # hashtable [Ordered] accelerator.\n    foreach ($Field in $StructFields.Keys)\n    {\n        $Index = $StructFields[$Field]['Position']\n        $Fields[$Index] = @{FieldName = $Field; Properties = $StructFields[$Field]}\n    }\n\n    foreach ($Field in $Fields)\n    {\n        $FieldName = $Field['FieldName']\n        $FieldProp = $Field['Properties']\n\n        $Offset = $FieldProp['Offset']\n        $Type = $FieldProp['Type']\n        $MarshalAs = $FieldProp['MarshalAs']\n\n        $NewField = $StructBuilder.DefineField($FieldName, $Type, 'Public')\n\n        if ($MarshalAs)\n        {\n            $UnmanagedType = $MarshalAs[0] -as ([Runtime.InteropServices.UnmanagedType])\n            if ($MarshalAs[1])\n            {\n                $Size = $MarshalAs[1]\n                $AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($ConstructorInfo,\n                    $UnmanagedType, $SizeConst, @($Size))\n            }\n            else\n            {\n                $AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($ConstructorInfo, [Object[]] @($UnmanagedType))\n            }\n            \n            $NewField.SetCustomAttribute($AttribBuilder)\n        }\n\n        if ($ExplicitLayout) { $NewField.SetOffset($Offset) }\n    }\n\n    # Make the struct aware of its own size.\n    # No more having to call [Runtime.InteropServices.Marshal]::SizeOf!\n    $SizeMethod = $StructBuilder.DefineMethod('GetSize',\n        'Public, Static',\n        [Int],\n        [Type[]] @())\n    $ILGenerator = $SizeMethod.GetILGenerator()\n    # Thanks for the help, Jason Shirk!\n    $ILGenerator.Emit([Reflection.Emit.OpCodes]::Ldtoken, $StructBuilder)\n    $ILGenerator.Emit([Reflection.Emit.OpCodes]::Call,\n        [Type].GetMethod('GetTypeFromHandle'))\n    $ILGenerator.Emit([Reflection.Emit.OpCodes]::Call,\n        [Runtime.InteropServices.Marshal].GetMethod('SizeOf', [Type[]] @([Type])))\n    $ILGenerator.Emit([Reflection.Emit.OpCodes]::Ret)\n\n    # Allow for explicit casting from an IntPtr\n    # No more having to call [Runtime.InteropServices.Marshal]::PtrToStructure!\n    $ImplicitConverter = $StructBuilder.DefineMethod('op_Implicit',\n        'PrivateScope, Public, Static, HideBySig, SpecialName',\n        $StructBuilder,\n        [Type[]] @([IntPtr]))\n    $ILGenerator2 = $ImplicitConverter.GetILGenerator()\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Nop)\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ldarg_0)\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ldtoken, $StructBuilder)\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Call,\n        [Type].GetMethod('GetTypeFromHandle'))\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Call,\n        [Runtime.InteropServices.Marshal].GetMethod('PtrToStructure', [Type[]] @([IntPtr], [Type])))\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Unbox_Any, $StructBuilder)\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ret)\n\n    $StructBuilder.CreateType()\n}\n#endregion PSReflect\n\n$mod = New-InMemoryModule -ModuleName Atom\n\n#region FunctionDefinitions\n$FunctionDefinitions = @(\n    (func kernel32 GlobalGetAtomName ([UInt32]) @(\n        [UInt16], #_In_  ATOM   nAtom\n        [IntPtr], #_Out_ LPTSTR lpBuffer\n        [UInt32]  #_In_  int    nSize\n    ) -EntryPoint GlobalGetAtomName -SetLastError)\n)\n#endregion FunctionDefinitions\n\n#region Windows API Functions\nfunction GlobalGetAtomName\n{\n    <#\n    .SYNOPSIS\n\n    Retrieves a copy of the character string associated with the specified global atom.\n\n    .DESCRIPTION\n\n    The string returned for an integer atom (an atom whose value is in the range 0x0001 to 0xBFFF) is a null-terminated string in which the first character is a pound sign (#) and the remaining characters represent the unsigned integer atom value.\n\n    .PARAMETER AtomIndex\n\n    The global atom (index) associated with the character string to be retrieved.\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: PSReflect\n    Optional Dependencies: None\n\n    (func kernel32 GlobalGetAtomName ([UInt32]) @(\n        [UInt16],  #_In_  ATOM   nAtom\n        [string].MakeByRefType(), #_Out_ LPTSTR lpBuffer\n        [UInt16]   #_In_  int    nSize\n    ) -EntryPoint GlobalGetAtomName -SetLastError)\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/ms649063(v=vs.85).aspx\n\n    .EXAMPLE\n\n    #>\n\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [UInt16]\n        $AtomIndex\n    )\n\n    $AtomName = [System.Runtime.InteropServices.Marshal]::AllocHGlobal(1024)\n\n    $SUCCESS = $kernel32::GlobalGetAtomName($AtomIndex, $AtomName, 1024); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n\n    if($SUCCESS -eq 0)\n    {\n        throw \"[GlobalGetAtomName]: Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n\n    Write-Output ([System.Runtime.InteropServices.Marshal]::PtrToStringUni($AtomName))\n}\n#endregion Windows API Functions\n\n$Types = $FunctionDefinitions | Add-Win32Type -Module $mod -Namespace ArpCache\n$kernel32 = $Types['kernel32']\n\nStart-AceScript -Uri https://10.182.18.200 -SweepId $args[0] -ScanId ([Guid]::NewGuid()) -RoutingKey siem -Thumbprint 8D1DB3B7B85B6F9E9DE87B291DF66692A10240AE"
  },
  {
    "path": "ACE-Management/PS-ACE/Scripts/ACE_Get-InjectedThread.ps1",
    "content": "function Start-AceScript\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $SweepId,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $ScanId,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $RoutingKey,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Thumbprint\n    )\n\n    $HostFQDN = Get-WmiObject Win32_ComputerSystem -Property 'Name','Domain' | ForEach-Object {\"$($_.Name).$($_.Domain)\"}\n    $ResultDate = (Get-Date).ToString(\"yyyyMMddThhmmssmsmsZ\")\n\n    $dataList = New-Object -TypeName System.Collections.Generic.List['string']\n\n    foreach($o in (Get-InjectedThread))\n    {\n        $o.Add('ComputerName', $HostFQDN)\n        $o.Add('ScanType', 'InjectedThread')\n        $o.Add('SweepId', $SweepId)\n        $o.Add('ScanId', $ScanId)\n        $o.Add('ResultDate', $ResultDate)\n\n        $message = ConvertTo-JsonV2 -InputObject $o\n        $dataList.Add($message)\n    }\n\n    $props = @{\n        ComputerName = $HostFQDN\n        ScanType     = 'InjectedThread'\n        RoutingKey   = $RoutingKey\n        ResultDate   = $ResultDate\n        ScanId       = $ScanId\n        Data         = $dataList.ToArray()\n    }\n\n    $body = (ConvertTo-JsonV2 -InputObject $props)\n    \n    Write-Host $body\n    \n    Invoke-AceWebRequest -Thumbprint $Thumbprint -Uri \"$($Uri)/ace/result/$($SweepId)\" -Body $body\n}\n\nfunction ConvertTo-JsonV2 \n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        $InputObject\n    )\n\n    Begin \n    {\n        $null = [System.Reflection.Assembly]::LoadWithPartialName(\"System.Web.Extensions\")\n        $Serializer = New-Object System.Web.Script.Serialization.JavaScriptSerializer\n    }\n\n    Process \n    {\n        try \n        {\n            $Serializer.Serialize($InputObject)\n        } \n        catch \n        {\n            Write-Error $_\n        }    \n    }\n}\n\nfunction Invoke-AceWebRequest\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Thumbprint,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Body\n    )\n\n    [Net.ServicePointManager]::ServerCertificateValidationCallback = {\n        $Thumbprint = $Thumbprint\n        $certificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]$args[1]\n    \n        if ($certificate -eq $null)\n        {\n            $Host.UI.WriteErrorLine(\"Null certificate.\")\n            return $true\n        }\n    \n        if ($certificate.Thumbprint -eq $Thumbprint)\n        {\n            return $true\n        }\n        else\n        {\n            $Host.UI.WriteErrorLine(\"Thumbprint mismatch. Certificate thumbprint $($certificate.Thumbprint)\")\n        }\n    \n        return $false\n    }\n\n    try\n    {\n        Write-Host \"URI: $($Uri)\"\n\n        # Create web request\n        $WebRequest = [Net.WebRequest]::Create($uri)\n        $WebRequest.Method = 'Post'\n        $WebRequest.ContentType = 'application/json'\n        $WebRequest.Headers.Add('X-API-Version:1.0')\n\n        $byteArray = [System.Text.Encoding]::UTF8.GetBytes($Body)\n        $Webrequest.ContentLength = $byteArray.Length\n        \n        $dataStream = $Webrequest.GetRequestStream()            \n        $dataStream.Write($byteArray, 0, $byteArray.Length)\n        $dataStream.Close()\n\n        # Get response stream\n        $ResponseStream = $Webrequest.GetResponse().GetResponseStream()\n    \n        # Create a stream reader and read the stream returning the string value.\n        $StreamReader = New-Object System.IO.StreamReader -ArgumentList $ResponseStream\n        $StreamReader.ReadToEnd()\n    }\n    catch\n    {\n        Write-Error \"Failed: $($_.exception.innerexception.message)\"\n    }\n}\n\nfunction Get-InjectedThread\n{\n    <# \n    \n    .SYNOPSIS \n    \n    Looks for threads that were created as a result of code injection.\n    \n    .DESCRIPTION\n    \n    Memory resident malware (fileless malware) often uses a form of memory injection to get code execution. Get-InjectedThread looks at each running thread to determine if it is the result of memory injection.\n    \n    Common memory injection techniques that *can* be caught using this method include:\n    - Classic Injection (OpenProcess, VirtualAllocEx, WriteProcessMemory, CreateRemoteThread)\n    - Reflective DLL Injection\n    - Process Hollowing\n\n    NOTE: Nothing in security is a silver bullet. An attacker could modify their tactics to avoid detection using this methodology.\n    \n    .NOTES\n\n    Author - Jared Atkinson (@jaredcatkinson)\n\n    .EXAMPLE \n    \n    PS > Get-InjectedThread \n\n    ProcessName               : ThreadStart.exe\n    ProcessId                 : 7784\n    Path                      : C:\\Users\\tester\\Desktop\\ThreadStart.exe\n    KernelPath                : C:\\Users\\tester\\Desktop\\ThreadStart.exe\n    CommandLine               : \"C:\\Users\\tester\\Desktop\\ThreadStart.exe\"\n    PathMismatch              : False\n    ThreadId                  : 14512\n    AllocatedMemoryProtection : PAGE_EXECUTE_READWRITE\n    MemoryProtection          : PAGE_EXECUTE_READWRITE\n    MemoryState               : MEM_COMMIT\n    MemoryType                : MEM_PRIVATE\n    BasePriority              : 8\n    IsUniqueThreadToken       : False\n    Integrity                 : MEDIUM_MANDATORY_LEVEL\n    Privilege                 : SeChangeNotifyPrivilege\n    LogonId                   : 999\n    SecurityIdentifier        : S-1-5-21-386661145-2656271985-3844047388-1001\n    UserName                  : DESKTOP-HMTGQ0R\\SYSTEM\n    LogonSessionStartTime     : 3/15/2017 5:45:38 PM\n    LogonType                 : System\n    AuthenticationPackage     : NTLM\n    BaseAddress               : 4390912\n    Size                      : 4096\n    Bytes                     : {144, 195, 0, 0...}\n    \n    #>\n\n    [CmdletBinding()]\n    param\n    (\n\n    )\n\n    $hSnapshot = CreateToolhelp32Snapshot -ProcessId 0 -Flags 4\n\n    $Thread = Thread32First -SnapshotHandle $hSnapshot\n    do\n    {\n        $proc = Get-Process -Id $Thread.th32OwnerProcessId -ErrorAction SilentlyContinue\n        \n        if($Thread.th32OwnerProcessId -ne 0 -and $Thread.th32OwnerProcessId -ne 4)\n        {\n            $hThread = OpenThread -ThreadId $Thread.th32ThreadID -DesiredAccess $THREAD_ALL_ACCESS -InheritHandle $false\n            if($hThread -ne 0)\n            {\n                $BaseAddress = NtQueryInformationThread -ThreadHandle $hThread\n                $hProcess = OpenProcess -ProcessId $Thread.th32OwnerProcessID -DesiredAccess $PROCESS_ALL_ACCESS -InheritHandle $false\n                \n                if($hProcess -ne 0)\n                {\n                    $memory_basic_info = VirtualQueryEx -ProcessHandle $hProcess -BaseAddress $BaseAddress\n                    $AllocatedMemoryProtection = $memory_basic_info.AllocationProtect -as $MemProtection\n                    $MemoryProtection = $memory_basic_info.Protect -as $MemProtection\n                    $MemoryState = $memory_basic_info.State -as $MemState\n                    $MemoryType = $memory_basic_info.Type -as $MemType\n                    \n                    if($MemoryState -eq $MemState::MEM_COMMIT -and $MemoryType -ne $MemType::MEM_IMAGE)\n                    {   \n                        $buf = ReadProcessMemory -ProcessHandle $hProcess -BaseAddress $BaseAddress -Size 100\n                        $proc = Get-WmiObject Win32_Process -Filter \"ProcessId = '$($Thread.th32OwnerProcessID)'\"\n                        $KernelPath = QueryFullProcessImageName -ProcessHandle $hProcess\n                        $PathMismatch = $proc.Path.ToLower() -ne $KernelPath.ToLower()\n                                    \n                        # check if thread has unique token\n                        try\n                        {\n                            $hThreadToken = OpenThreadToken -ThreadHandle $hThread -DesiredAccess $TOKEN_ALL_ACCESS\n                            $SID = GetTokenInformation -TokenHandle $hThreadToken -TokenInformationClass 1\n                            $Privs = GetTokenInformation -TokenHandle $hThreadToken -TokenInformationClass 3 \n                            $LogonSession = GetTokenInformation -TokenHandle $hThreadToken -TokenInformationClass 17 \n                            $Integrity = GetTokenInformation -TokenHandle $hThreadToken -TokenInformationClass 25 \n                            $IsUniqueThreadToken = $true               \n                        }\n                        catch\n                        {\n                            $hProcessToken = OpenProcessToken -ProcessHandle $hProcess -DesiredAccess $TOKEN_ALL_ACCESS\n                            $SID = GetTokenInformation -TokenHandle $hProcessToken -TokenInformationClass 1\n                            $Privs = GetTokenInformation -TokenHandle $hProcessToken -TokenInformationClass 3 \n                            $LogonSession = GetTokenInformation -TokenHandle $hProcessToken -TokenInformationClass 17 \n                            $Integrity = GetTokenInformation -TokenHandle $hProcessToken -TokenInformationClass 25\n                            $IsUniqueThreadToken = $false\n                        }\n                        \n                        $props = @{\n                            ProcessName = [string]$proc.Name\n                            ProcessId = $proc.ProcessId\n                            Path = [string]$proc.Path\n                            KernelPath = [string]$KernelPath\n                            CommandLine = [string]$proc.CommandLine\n                            PathMismatch = [string]$PathMismatch\n                            ThreadId = $Thread.th32ThreadId\n                            AllocatedMemoryProtection = [string]$AllocatedMemoryProtection\n                            MemoryProtection = [string]$MemoryProtection\n                            MemoryState = [string]$MemoryState\n                            MemoryType = [string]$MemoryType\n                            BasePriority = [string]$Thread.tpBasePri\n                            IsUniqueThreadToken = $IsUniqueThreadToken\n                            Integrity = [string]$Integrity\n                            Privilege = [string]$Privs\n                            LogonId = $LogonSession.LogonId\n                            SecurityIdentifier = [string]$SID\n                            UserName = \"$($LogonSession.Domain)\\$($LogonSession.UserName)\"\n                            LogonSessionStartTime = [string]$LogonSession.StartTime\n                            LogonType = [string]$LogonSession.LogonType\n                            AuthenticationPackage = [string]$LogonSession.AuthenticationPackage\n                            BaseAddress = [string]$BaseAddress\n                            Size = $memory_basic_info.RegionSize\n                        }\n                        \n                        Write-Output $props\n                    }\n                    CloseHandle($hProcess)\n                }\n            }\n            CloseHandle($hThread)\n        }\n    } while($Kernel32::Thread32Next($hSnapshot, [ref]$Thread))\n    CloseHandle($hSnapshot)\n}\n\nfunction Stop-Thread\n{\n    <# \n    \n    .SYNOPSIS \n    \n    Terminates a specified Thread. \n\n    .DESCRIPTION\n\n    The Stop-Thread function can stop an individual thread in a process. This is quite useful in situations where code injection (dll injection) techniques have been used by attackers. If an attacker runs their malicious code in a thread within a critical process, then Stop-Thread can kill the malicious thread without hurting the critical process.\n\n    .NOTES\n\n    Author - Jared Atkinson (@jaredcatkinson)\n\n    .EXAMPLE \n    \n    PS > Stop-Thread -ThreadId 1776 \n\n    #>\n\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory = $true, Position = 0)]\n        [UInt32]\n        $ThreadId\n    )\n    \n    $hThread = OpenThread -ThreadId $ThreadId -DesiredAccess $THREAD_TERMINATE\n    TerminateThread -ThreadHandle $hThread\n    CloseHandle -Handle $hThread\n}\n\n<#\nAuthor: Lee Christensen (@tifkin_)\nLicense: BSD 3-Clause\nRequired Dependencies: None\nOptional Dependencies: None\n#>\nfunction Get-LogonSession\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [UInt32]\n        $LogonId\n    )\n    \n    $LogonMap = @{}\n    Get-WmiObject Win32_LoggedOnUser  | %{\n    \n        $Identity = $_.Antecedent | Select-String 'Domain=\"(.*)\",Name=\"(.*)\"'\n        $LogonSession = $_.Dependent | Select-String 'LogonId=\"(\\d+)\"'\n\n        $LogonMap[$LogonSession.Matches[0].Groups[1].Value] = New-Object PSObject -Property @{\n            Domain = $Identity.Matches[0].Groups[1].Value\n            UserName = $Identity.Matches[0].Groups[2].Value\n        }\n    }\n\n    Get-WmiObject Win32_LogonSession -Filter \"LogonId = `\"$($LogonId)`\"\" | %{\n        $LogonType = $Null\n        switch($_.LogonType) {\n            $null {$LogonType = 'None'}\n            0 { $LogonType = 'System' }\n            2 { $LogonType = 'Interactive' }\n            3 { $LogonType = 'Network' }\n            4 { $LogonType = 'Batch' }\n            5 { $LogonType = 'Service' }\n            6 { $LogonType = 'Proxy' }\n            7 { $LogonType = 'Unlock' }\n            8 { $LogonType = 'NetworkCleartext' }\n            9 { $LogonType = 'NewCredentials' }\n            10 { $LogonType = 'RemoteInteractive' }\n            11 { $LogonType = 'CachedInteractive' }\n            12 { $LogonType = 'CachedRemoteInteractive' }\n            13 { $LogonType = 'CachedUnlock' }\n            default { $LogonType = $_.LogonType}\n        }\n\n        New-Object PSObject -Property @{\n            UserName = $LogonMap[$_.LogonId].UserName\n            Domain = $LogonMap[$_.LogonId].Domain\n            LogonId = $_.LogonId\n            LogonType = $LogonType\n            AuthenticationPackage = $_.AuthenticationPackage\n            Caption = $_.Caption\n            Description = $_.Description\n            InstallDate = $_.InstallDate\n            Name = $_.Name\n            StartTime = $_.ConvertToDateTime($_.StartTime)\n        }\n    }\n}\n\n#region PSReflect\n\nfunction New-InMemoryModule\n{\n<#\n.SYNOPSIS\n\nCreates an in-memory assembly and module\n\nAuthor: Matthew Graeber (@mattifestation)\nLicense: BSD 3-Clause\nRequired Dependencies: None\nOptional Dependencies: None\n \n.DESCRIPTION\n\nWhen defining custom enums, structs, and unmanaged functions, it is\nnecessary to associate to an assembly module. This helper function\ncreates an in-memory module that can be passed to the 'enum',\n'struct', and Add-Win32Type functions.\n\n.PARAMETER ModuleName\n\nSpecifies the desired name for the in-memory assembly and module. If\nModuleName is not provided, it will default to a GUID.\n\n.EXAMPLE\n\n$Module = New-InMemoryModule -ModuleName Win32\n#>\n\n    Param\n    (\n        [Parameter(Position = 0)]\n        [ValidateNotNullOrEmpty()]\n        [String]\n        $ModuleName = [Guid]::NewGuid().ToString()\n    )\n\n    $AppDomain = [Reflection.Assembly].Assembly.GetType('System.AppDomain').GetProperty('CurrentDomain').GetValue($null, @())\n    $LoadedAssemblies = $AppDomain.GetAssemblies()\n\n    foreach ($Assembly in $LoadedAssemblies) {\n        if ($Assembly.FullName -and ($Assembly.FullName.Split(',')[0] -eq $ModuleName)) {\n            return $Assembly\n        }\n    }\n\n    $DynAssembly = New-Object Reflection.AssemblyName($ModuleName)\n    $Domain = $AppDomain\n    $AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, 'Run')\n    $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule($ModuleName, $False)\n\n    return $ModuleBuilder\n}\n\n# A helper function used to reduce typing while defining function\n# prototypes for Add-Win32Type.\nfunction func\n{\n    Param\n    (\n        [Parameter(Position = 0, Mandatory = $True)]\n        [String]\n        $DllName,\n\n        [Parameter(Position = 1, Mandatory = $True)]\n        [string]\n        $FunctionName,\n\n        [Parameter(Position = 2, Mandatory = $True)]\n        [Type]\n        $ReturnType,\n\n        [Parameter(Position = 3)]\n        [Type[]]\n        $ParameterTypes,\n\n        [Parameter(Position = 4)]\n        [Runtime.InteropServices.CallingConvention]\n        $NativeCallingConvention,\n\n        [Parameter(Position = 5)]\n        [Runtime.InteropServices.CharSet]\n        $Charset,\n\n        [String]\n        $EntryPoint,\n\n        [Switch]\n        $SetLastError\n    )\n\n    $Properties = @{\n        DllName = $DllName\n        FunctionName = $FunctionName\n        ReturnType = $ReturnType\n    }\n\n    if ($ParameterTypes) { $Properties['ParameterTypes'] = $ParameterTypes }\n    if ($NativeCallingConvention) { $Properties['NativeCallingConvention'] = $NativeCallingConvention }\n    if ($Charset) { $Properties['Charset'] = $Charset }\n    if ($SetLastError) { $Properties['SetLastError'] = $SetLastError }\n    if ($EntryPoint) { $Properties['EntryPoint'] = $EntryPoint }\n\n    New-Object PSObject -Property $Properties\n}\n\nfunction Add-Win32Type\n{\n<#\n.SYNOPSIS\n\nCreates a .NET type for an unmanaged Win32 function.\n\nAuthor: Matthew Graeber (@mattifestation)\nLicense: BSD 3-Clause\nRequired Dependencies: None\nOptional Dependencies: func\n \n.DESCRIPTION\n\nAdd-Win32Type enables you to easily interact with unmanaged (i.e.\nWin32 unmanaged) functions in PowerShell. After providing\nAdd-Win32Type with a function signature, a .NET type is created\nusing reflection (i.e. csc.exe is never called like with Add-Type).\n\nThe 'func' helper function can be used to reduce typing when defining\nmultiple function definitions.\n\n.PARAMETER DllName\n\nThe name of the DLL.\n\n.PARAMETER FunctionName\n\nThe name of the target function.\n\n.PARAMETER EntryPoint\n\nThe DLL export function name. This argument should be specified if the\nspecified function name is different than the name of the exported\nfunction.\n\n.PARAMETER ReturnType\n\nThe return type of the function.\n\n.PARAMETER ParameterTypes\n\nThe function parameters.\n\n.PARAMETER NativeCallingConvention\n\nSpecifies the native calling convention of the function. Defaults to\nstdcall.\n\n.PARAMETER Charset\n\nIf you need to explicitly call an 'A' or 'W' Win32 function, you can\nspecify the character set.\n\n.PARAMETER SetLastError\n\nIndicates whether the callee calls the SetLastError Win32 API\nfunction before returning from the attributed method.\n\n.PARAMETER Module\n\nThe in-memory module that will host the functions. Use\nNew-InMemoryModule to define an in-memory module.\n\n.PARAMETER Namespace\n\nAn optional namespace to prepend to the type. Add-Win32Type defaults\nto a namespace consisting only of the name of the DLL.\n\n.EXAMPLE\n\n$Mod = New-InMemoryModule -ModuleName Win32\n\n$FunctionDefinitions = @(\n  (func kernel32 GetProcAddress ([IntPtr]) @([IntPtr], [String]) -Charset Ansi -SetLastError),\n  (func kernel32 GetModuleHandle ([Intptr]) @([String]) -SetLastError),\n  (func ntdll RtlGetCurrentPeb ([IntPtr]) @())\n)\n\n$Types = $FunctionDefinitions | Add-Win32Type -Module $Mod -Namespace 'Win32'\n$Kernel32 = $Types['kernel32']\n$Ntdll = $Types['ntdll']\n$Ntdll::RtlGetCurrentPeb()\n$ntdllbase = $Kernel32::GetModuleHandle('ntdll')\n$Kernel32::GetProcAddress($ntdllbase, 'RtlGetCurrentPeb')\n\n.NOTES\n\nInspired by Lee Holmes' Invoke-WindowsApi http://poshcode.org/2189\n\nWhen defining multiple function prototypes, it is ideal to provide\nAdd-Win32Type with an array of function signatures. That way, they\nare all incorporated into the same in-memory module.\n#>\n\n    [OutputType([Hashtable])]\n    Param(\n        [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)]\n        [String]\n        $DllName,\n\n        [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)]\n        [String]\n        $FunctionName,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [String]\n        $EntryPoint,\n\n        [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)]\n        [Type]\n        $ReturnType,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [Type[]]\n        $ParameterTypes,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [Runtime.InteropServices.CallingConvention]\n        $NativeCallingConvention = [Runtime.InteropServices.CallingConvention]::StdCall,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [Runtime.InteropServices.CharSet]\n        $Charset = [Runtime.InteropServices.CharSet]::Auto,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [Switch]\n        $SetLastError,\n\n        [Parameter(Mandatory = $True)]\n        [ValidateScript({($_ -is [Reflection.Emit.ModuleBuilder]) -or ($_ -is [Reflection.Assembly])})]\n        $Module,\n\n        [ValidateNotNull()]\n        [String]\n        $Namespace = ''\n    )\n\n    BEGIN\n    {\n        $TypeHash = @{}\n    }\n\n    PROCESS\n    {\n        if ($Module -is [Reflection.Assembly])\n        {\n            if ($Namespace)\n            {\n                $TypeHash[$DllName] = $Module.GetType(\"$Namespace.$DllName\")\n            }\n            else\n            {\n                $TypeHash[$DllName] = $Module.GetType($DllName)\n            }\n        }\n        else\n        {\n            # Define one type for each DLL\n            if (!$TypeHash.ContainsKey($DllName))\n            {\n                if ($Namespace)\n                {\n                    $TypeHash[$DllName] = $Module.DefineType(\"$Namespace.$DllName\", 'Public,BeforeFieldInit')\n                }\n                else\n                {\n                    $TypeHash[$DllName] = $Module.DefineType($DllName, 'Public,BeforeFieldInit')\n                }\n            }\n\n            $Method = $TypeHash[$DllName].DefineMethod(\n                $FunctionName,\n                'Public,Static,PinvokeImpl',\n                $ReturnType,\n                $ParameterTypes)\n\n            # Make each ByRef parameter an Out parameter\n            $i = 1\n            foreach($Parameter in $ParameterTypes)\n            {\n                if ($Parameter.IsByRef)\n                {\n                    [void] $Method.DefineParameter($i, 'Out', $null)\n                }\n\n                $i++\n            }\n\n            $DllImport = [Runtime.InteropServices.DllImportAttribute]\n            $SetLastErrorField = $DllImport.GetField('SetLastError')\n            $CallingConventionField = $DllImport.GetField('CallingConvention')\n            $CharsetField = $DllImport.GetField('CharSet')\n            $EntryPointField = $DllImport.GetField('EntryPoint')\n            if ($SetLastError) { $SLEValue = $True } else { $SLEValue = $False }\n\n            if ($PSBoundParameters['EntryPoint']) { $ExportedFuncName = $EntryPoint } else { $ExportedFuncName = $FunctionName }\n\n            # Equivalent to C# version of [DllImport(DllName)]\n            $Constructor = [Runtime.InteropServices.DllImportAttribute].GetConstructor([String])\n            $DllImportAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($Constructor,\n                $DllName, [Reflection.PropertyInfo[]] @(), [Object[]] @(),\n                [Reflection.FieldInfo[]] @($SetLastErrorField,\n                                           $CallingConventionField,\n                                           $CharsetField,\n                                           $EntryPointField),\n                [Object[]] @($SLEValue,\n                             ([Runtime.InteropServices.CallingConvention] $NativeCallingConvention),\n                             ([Runtime.InteropServices.CharSet] $Charset),\n                             $ExportedFuncName))\n\n            $Method.SetCustomAttribute($DllImportAttribute)\n        }\n    }\n\n    END\n    {\n        if ($Module -is [Reflection.Assembly])\n        {\n            return $TypeHash\n        }\n\n        $ReturnTypes = @{}\n\n        foreach ($Key in $TypeHash.Keys)\n        {\n            $Type = $TypeHash[$Key].CreateType()\n            \n            $ReturnTypes[$Key] = $Type\n        }\n\n        return $ReturnTypes\n    }\n}\n\nfunction psenum\n{\n<#\n.SYNOPSIS\n\nCreates an in-memory enumeration for use in your PowerShell session.\n\nAuthor: Matthew Graeber (@mattifestation)\nLicense: BSD 3-Clause\nRequired Dependencies: None\nOptional Dependencies: None\n \n.DESCRIPTION\n\nThe 'psenum' function facilitates the creation of enums entirely in\nmemory using as close to a \"C style\" as PowerShell will allow.\n\n.PARAMETER Module\n\nThe in-memory module that will host the enum. Use\nNew-InMemoryModule to define an in-memory module.\n\n.PARAMETER FullName\n\nThe fully-qualified name of the enum.\n\n.PARAMETER Type\n\nThe type of each enum element.\n\n.PARAMETER EnumElements\n\nA hashtable of enum elements.\n\n.PARAMETER Bitfield\n\nSpecifies that the enum should be treated as a bitfield.\n\n.EXAMPLE\n\n$Mod = New-InMemoryModule -ModuleName Win32\n\n$ImageSubsystem = psenum $Mod PE.IMAGE_SUBSYSTEM UInt16 @{\n    UNKNOWN =                  0\n    NATIVE =                   1 # Image doesn't require a subsystem.\n    WINDOWS_GUI =              2 # Image runs in the Windows GUI subsystem.\n    WINDOWS_CUI =              3 # Image runs in the Windows character subsystem.\n    OS2_CUI =                  5 # Image runs in the OS/2 character subsystem.\n    POSIX_CUI =                7 # Image runs in the Posix character subsystem.\n    NATIVE_WINDOWS =           8 # Image is a native Win9x driver.\n    WINDOWS_CE_GUI =           9 # Image runs in the Windows CE subsystem.\n    EFI_APPLICATION =          10\n    EFI_BOOT_SERVICE_DRIVER =  11\n    EFI_RUNTIME_DRIVER =       12\n    EFI_ROM =                  13\n    XBOX =                     14\n    WINDOWS_BOOT_APPLICATION = 16\n}\n\n.NOTES\n\nPowerShell purists may disagree with the naming of this function but\nagain, this was developed in such a way so as to emulate a \"C style\"\ndefinition as closely as possible. Sorry, I'm not going to name it\nNew-Enum. :P\n#>\n\n    [OutputType([Type])]\n    Param\n    (\n        [Parameter(Position = 0, Mandatory = $True)]\n        [ValidateScript({($_ -is [Reflection.Emit.ModuleBuilder]) -or ($_ -is [Reflection.Assembly])})]\n        $Module,\n\n        [Parameter(Position = 1, Mandatory = $True)]\n        [ValidateNotNullOrEmpty()]\n        [String]\n        $FullName,\n\n        [Parameter(Position = 2, Mandatory = $True)]\n        [Type]\n        $Type,\n\n        [Parameter(Position = 3, Mandatory = $True)]\n        [ValidateNotNullOrEmpty()]\n        [Hashtable]\n        $EnumElements,\n\n        [Switch]\n        $Bitfield\n    )\n\n    if ($Module -is [Reflection.Assembly])\n    {\n        return ($Module.GetType($FullName))\n    }\n\n    $EnumType = $Type -as [Type]\n\n    $EnumBuilder = $Module.DefineEnum($FullName, 'Public', $EnumType)\n\n    if ($Bitfield)\n    {\n        $FlagsConstructor = [FlagsAttribute].GetConstructor(@())\n        $FlagsCustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($FlagsConstructor, @())\n        $EnumBuilder.SetCustomAttribute($FlagsCustomAttribute)\n    }\n\n    foreach ($Key in $EnumElements.Keys)\n    {\n        # Apply the specified enum type to each element\n        $null = $EnumBuilder.DefineLiteral($Key, $EnumElements[$Key] -as $EnumType)\n    }\n\n    $EnumBuilder.CreateType()\n}\n\n# A helper function used to reduce typing while defining struct\n# fields.\nfunction field\n{\n    Param\n    (\n        [Parameter(Position = 0, Mandatory = $True)]\n        [UInt16]\n        $Position,\n        \n        [Parameter(Position = 1, Mandatory = $True)]\n        [Type]\n        $Type,\n        \n        [Parameter(Position = 2)]\n        [UInt16]\n        $Offset,\n        \n        [Object[]]\n        $MarshalAs\n    )\n\n    @{\n        Position = $Position\n        Type = $Type -as [Type]\n        Offset = $Offset\n        MarshalAs = $MarshalAs\n    }\n}\n\nfunction struct\n{\n<#\n.SYNOPSIS\n\nCreates an in-memory struct for use in your PowerShell session.\n\nAuthor: Matthew Graeber (@mattifestation)\nLicense: BSD 3-Clause\nRequired Dependencies: None\nOptional Dependencies: field\n \n.DESCRIPTION\n\nThe 'struct' function facilitates the creation of structs entirely in\nmemory using as close to a \"C style\" as PowerShell will allow. Struct\nfields are specified using a hashtable where each field of the struct\nis comprosed of the order in which it should be defined, its .NET\ntype, and optionally, its offset and special marshaling attributes.\n\nOne of the features of 'struct' is that after your struct is defined,\nit will come with a built-in GetSize method as well as an explicit\nconverter so that you can easily cast an IntPtr to the struct without\nrelying upon calling SizeOf and/or PtrToStructure in the Marshal\nclass.\n\n.PARAMETER Module\n\nThe in-memory module that will host the struct. Use\nNew-InMemoryModule to define an in-memory module.\n\n.PARAMETER FullName\n\nThe fully-qualified name of the struct.\n\n.PARAMETER StructFields\n\nA hashtable of fields. Use the 'field' helper function to ease\ndefining each field.\n\n.PARAMETER PackingSize\n\nSpecifies the memory alignment of fields.\n\n.PARAMETER ExplicitLayout\n\nIndicates that an explicit offset for each field will be specified.\n\n.EXAMPLE\n\n$Mod = New-InMemoryModule -ModuleName Win32\n\n$ImageDosSignature = psenum $Mod PE.IMAGE_DOS_SIGNATURE UInt16 @{\n    DOS_SIGNATURE =    0x5A4D\n    OS2_SIGNATURE =    0x454E\n    OS2_SIGNATURE_LE = 0x454C\n    VXD_SIGNATURE =    0x454C\n}\n\n$ImageDosHeader = struct $Mod PE.IMAGE_DOS_HEADER @{\n    e_magic =    field 0 $ImageDosSignature\n    e_cblp =     field 1 UInt16\n    e_cp =       field 2 UInt16\n    e_crlc =     field 3 UInt16\n    e_cparhdr =  field 4 UInt16\n    e_minalloc = field 5 UInt16\n    e_maxalloc = field 6 UInt16\n    e_ss =       field 7 UInt16\n    e_sp =       field 8 UInt16\n    e_csum =     field 9 UInt16\n    e_ip =       field 10 UInt16\n    e_cs =       field 11 UInt16\n    e_lfarlc =   field 12 UInt16\n    e_ovno =     field 13 UInt16\n    e_res =      field 14 UInt16[] -MarshalAs @('ByValArray', 4)\n    e_oemid =    field 15 UInt16\n    e_oeminfo =  field 16 UInt16\n    e_res2 =     field 17 UInt16[] -MarshalAs @('ByValArray', 10)\n    e_lfanew =   field 18 Int32\n}\n\n# Example of using an explicit layout in order to create a union.\n$TestUnion = struct $Mod TestUnion @{\n    field1 = field 0 UInt32 0\n    field2 = field 1 IntPtr 0\n} -ExplicitLayout\n\n.NOTES\n\nPowerShell purists may disagree with the naming of this function but\nagain, this was developed in such a way so as to emulate a \"C style\"\ndefinition as closely as possible. Sorry, I'm not going to name it\nNew-Struct. :P\n#>\n\n    [OutputType([Type])]\n    Param\n    (\n        [Parameter(Position = 1, Mandatory = $True)]\n        [ValidateScript({($_ -is [Reflection.Emit.ModuleBuilder]) -or ($_ -is [Reflection.Assembly])})]\n        $Module,\n\n        [Parameter(Position = 2, Mandatory = $True)]\n        [ValidateNotNullOrEmpty()]\n        [String]\n        $FullName,\n\n        [Parameter(Position = 3, Mandatory = $True)]\n        [ValidateNotNullOrEmpty()]\n        [Hashtable]\n        $StructFields,\n\n        [Reflection.Emit.PackingSize]\n        $PackingSize = [Reflection.Emit.PackingSize]::Unspecified,\n\n        [Switch]\n        $ExplicitLayout\n    )\n\n    if ($Module -is [Reflection.Assembly])\n    {\n        return ($Module.GetType($FullName))\n    }\n\n    [Reflection.TypeAttributes] $StructAttributes = 'AnsiClass,\n        Class,\n        Public,\n        Sealed,\n        BeforeFieldInit'\n\n    if ($ExplicitLayout)\n    {\n        $StructAttributes = $StructAttributes -bor [Reflection.TypeAttributes]::ExplicitLayout\n    }\n    else\n    {\n        $StructAttributes = $StructAttributes -bor [Reflection.TypeAttributes]::SequentialLayout\n    }\n\n    $StructBuilder = $Module.DefineType($FullName, $StructAttributes, [ValueType], $PackingSize)\n    $ConstructorInfo = [Runtime.InteropServices.MarshalAsAttribute].GetConstructors()[0]\n    $SizeConst = @([Runtime.InteropServices.MarshalAsAttribute].GetField('SizeConst'))\n\n    $Fields = New-Object Hashtable[]($StructFields.Count)\n\n    # Sort each field according to the orders specified\n    # Unfortunately, PSv2 doesn't have the luxury of the\n    # hashtable [Ordered] accelerator.\n    foreach ($Field in $StructFields.Keys)\n    {\n        $Index = $StructFields[$Field]['Position']\n        $Fields[$Index] = @{FieldName = $Field; Properties = $StructFields[$Field]}\n    }\n\n    foreach ($Field in $Fields)\n    {\n        $FieldName = $Field['FieldName']\n        $FieldProp = $Field['Properties']\n\n        $Offset = $FieldProp['Offset']\n        $Type = $FieldProp['Type']\n        $MarshalAs = $FieldProp['MarshalAs']\n\n        $NewField = $StructBuilder.DefineField($FieldName, $Type, 'Public')\n\n        if ($MarshalAs)\n        {\n            $UnmanagedType = $MarshalAs[0] -as ([Runtime.InteropServices.UnmanagedType])\n            if ($MarshalAs[1])\n            {\n                $Size = $MarshalAs[1]\n                $AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($ConstructorInfo,\n                    $UnmanagedType, $SizeConst, @($Size))\n            }\n            else\n            {\n                $AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($ConstructorInfo, [Object[]] @($UnmanagedType))\n            }\n            \n            $NewField.SetCustomAttribute($AttribBuilder)\n        }\n\n        if ($ExplicitLayout) { $NewField.SetOffset($Offset) }\n    }\n\n    # Make the struct aware of its own size.\n    # No more having to call [Runtime.InteropServices.Marshal]::SizeOf!\n    $SizeMethod = $StructBuilder.DefineMethod('GetSize',\n        'Public, Static',\n        [Int],\n        [Type[]] @())\n    $ILGenerator = $SizeMethod.GetILGenerator()\n    # Thanks for the help, Jason Shirk!\n    $ILGenerator.Emit([Reflection.Emit.OpCodes]::Ldtoken, $StructBuilder)\n    $ILGenerator.Emit([Reflection.Emit.OpCodes]::Call,\n        [Type].GetMethod('GetTypeFromHandle'))\n    $ILGenerator.Emit([Reflection.Emit.OpCodes]::Call,\n        [Runtime.InteropServices.Marshal].GetMethod('SizeOf', [Type[]] @([Type])))\n    $ILGenerator.Emit([Reflection.Emit.OpCodes]::Ret)\n\n    # Allow for explicit casting from an IntPtr\n    # No more having to call [Runtime.InteropServices.Marshal]::PtrToStructure!\n    $ImplicitConverter = $StructBuilder.DefineMethod('op_Implicit',\n        'PrivateScope, Public, Static, HideBySig, SpecialName',\n        $StructBuilder,\n        [Type[]] @([IntPtr]))\n    $ILGenerator2 = $ImplicitConverter.GetILGenerator()\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Nop)\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ldarg_0)\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ldtoken, $StructBuilder)\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Call,\n        [Type].GetMethod('GetTypeFromHandle'))\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Call,\n        [Runtime.InteropServices.Marshal].GetMethod('PtrToStructure', [Type[]] @([IntPtr], [Type])))\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Unbox_Any, $StructBuilder)\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ret)\n\n    $StructBuilder.CreateType()\n}\n\n#endregion PSReflect\n\n#region PSReflect Definitions (Thread)\n\n$Module = New-InMemoryModule -ModuleName Thread\n\n$LuidAttributes = psenum $Module LuidAttributes UInt32 @{\n    DISABLED                            =   '0x00000000'\n    SE_PRIVILEGE_ENABLED_BY_DEFAULT     =   '0x00000001'\n    SE_PRIVILEGE_ENABLED                =   '0x00000002'\n    SE_PRIVILEGE_REMOVED                =   '0x00000004'\n    SE_PRIVILEGE_USED_FOR_ACCESS        =   '0x80000000'\n} -Bitfield\n\n$MemProtection = psenum $Module MemProtection UInt32 @{\n    PAGE_EXECUTE = 0x10\n    PAGE_EXECUTE_READ = 0x20\n    PAGE_EXECUTE_READWRITE = 0x40\n    PAGE_EXECUTE_WRITECOPY = 0x80\n    PAGE_NOACCESS = 0x01\n    PAGE_READONLY = 0x02\n    PAGE_READWRITE = 0x04\n    PAGE_WRITECOPY = 0x08\n    PAGE_TARGETS_INVALID = 0x40000000\n    PAGE_TARGETS_NO_UPDATE = 0x40000000\n    PAGE_GUARD = 0x100\n    PAGE_NOCACHE = 0x200\n    PAGE_WRITECOMBINE = 0x400\n} -Bitfield\n\n$MemState = psenum $Module MemState UInt32 @{\n    MEM_COMMIT = 0x1000\n    MEM_RESERVE = 0x2000\n    MEM_FREE = 0x10000\n}\n\n$MemType = psenum $Module MemType UInt32 @{\n    MEM_PRIVATE = 0x20000\n    MEM_MAPPED = 0x40000\n    MEM_IMAGE = 0x1000000\n}\n\n$SecurityEntity = psenum $Module SecurityEntity UInt32 @{\n    SeCreateTokenPrivilege              =   1\n    SeAssignPrimaryTokenPrivilege       =   2\n    SeLockMemoryPrivilege               =   3\n    SeIncreaseQuotaPrivilege            =   4\n    SeUnsolicitedInputPrivilege         =   5\n    SeMachineAccountPrivilege           =   6\n    SeTcbPrivilege                      =   7\n    SeSecurityPrivilege                 =   8\n    SeTakeOwnershipPrivilege            =   9\n    SeLoadDriverPrivilege               =   10\n    SeSystemProfilePrivilege            =   11\n    SeSystemtimePrivilege               =   12\n    SeProfileSingleProcessPrivilege     =   13\n    SeIncreaseBasePriorityPrivilege     =   14\n    SeCreatePagefilePrivilege           =   15\n    SeCreatePermanentPrivilege          =   16\n    SeBackupPrivilege                   =   17\n    SeRestorePrivilege                  =   18\n    SeShutdownPrivilege                 =   19\n    SeDebugPrivilege                    =   20\n    SeAuditPrivilege                    =   21\n    SeSystemEnvironmentPrivilege        =   22\n    SeChangeNotifyPrivilege             =   23\n    SeRemoteShutdownPrivilege           =   24\n    SeUndockPrivilege                   =   25\n    SeSyncAgentPrivilege                =   26\n    SeEnableDelegationPrivilege         =   27\n    SeManageVolumePrivilege             =   28\n    SeImpersonatePrivilege              =   29\n    SeCreateGlobalPrivilege             =   30\n    SeTrustedCredManAccessPrivilege     =   31\n    SeRelabelPrivilege                  =   32\n    SeIncreaseWorkingSetPrivilege       =   33\n    SeTimeZonePrivilege                 =   34\n    SeCreateSymbolicLinkPrivilege       =   35\n}\n\n$SidNameUser = psenum $Module SID_NAME_USE UInt32 @{\n  SidTypeUser                            = 1\n  SidTypeGroup                           = 2\n  SidTypeDomain                          = 3\n  SidTypeAlias                           = 4\n  SidTypeWellKnownGroup                  = 5\n  SidTypeDeletedAccount                  = 6\n  SidTypeInvalid                         = 7\n  SidTypeUnknown                         = 8\n  SidTypeComputer                        = 9\n}\n\n$TokenInformationClass = psenum $Module TOKEN_INFORMATION_CLASS UInt16 @{ \n  TokenUser                             = 1\n  TokenGroups                           = 2\n  TokenPrivileges                       = 3\n  TokenOwner                            = 4\n  TokenPrimaryGroup                     = 5\n  TokenDefaultDacl                      = 6\n  TokenSource                           = 7\n  TokenType                             = 8\n  TokenImpersonationLevel               = 9\n  TokenStatistics                       = 10\n  TokenRestrictedSids                   = 11\n  TokenSessionId                        = 12\n  TokenGroupsAndPrivileges              = 13\n  TokenSessionReference                 = 14\n  TokenSandBoxInert                     = 15\n  TokenAuditPolicy                      = 16\n  TokenOrigin                           = 17\n  TokenElevationType                    = 18\n  TokenLinkedToken                      = 19\n  TokenElevation                        = 20\n  TokenHasRestrictions                  = 21\n  TokenAccessInformation                = 22\n  TokenVirtualizationAllowed            = 23\n  TokenVirtualizationEnabled            = 24\n  TokenIntegrityLevel                   = 25\n  TokenUIAccess                         = 26\n  TokenMandatoryPolicy                  = 27\n  TokenLogonSid                         = 28\n  TokenIsAppContainer                   = 29\n  TokenCapabilities                     = 30\n  TokenAppContainerSid                  = 31\n  TokenAppContainerNumber               = 32\n  TokenUserClaimAttributes              = 33\n  TokenDeviceClaimAttributes            = 34\n  TokenRestrictedUserClaimAttributes    = 35\n  TokenRestrictedDeviceClaimAttributes  = 36\n  TokenDeviceGroups                     = 37\n  TokenRestrictedDeviceGroups           = 38\n  TokenSecurityAttributes               = 39\n  TokenIsRestricted                     = 40\n  MaxTokenInfoClass                     = 41\n}\n\n$LUID = struct $Module Luid @{\n    LowPart         =   field 0 $SecurityEntity\n    HighPart        =   field 1 Int32\n}\n\n$LUID_AND_ATTRIBUTES = struct $Module LuidAndAttributes @{\n    Luid            =   field 0 $LUID\n    Attributes      =   field 1 UInt32\n}\n\n$MEMORYBASICINFORMATION = struct $Module MEMORY_BASIC_INFORMATION @{\n  BaseAddress       = field 0 UIntPtr\n  AllocationBase    = field 1 UIntPtr\n  AllocationProtect = field 2 UInt32\n  RegionSize        = field 3 UIntPtr\n  State             = field 4 UInt32\n  Protect           = field 5 UInt32\n  Type              = field 6 UInt32\n}\n\n$SID_AND_ATTRIBUTES = struct $Module SidAndAttributes @{\n    Sid             =   field 0 IntPtr\n    Attributes      =   field 1 UInt32\n}\n\n$THREADENTRY32 = struct $Module THREADENTRY32 @{\n    dwSize          = field 0 UInt32\n    cntUsage        = field 1 UInt32\n    th32ThreadID    = field 2 UInt32\n    th32OwnerProcessID = field 3 UInt32\n    tpBasePri       = field 4 UInt32\n    tpDeltaPri      = field 5 UInt32\n    dwFlags         = field 6 UInt32\n}\n\n$TOKEN_MANDATORY_LABEL = struct $Module TokenMandatoryLabel @{\n    Label           = field 0 $SID_AND_ATTRIBUTES;\n}\n\n$TOKEN_ORIGIN = struct $Module TokenOrigin @{\n  OriginatingLogonSession = field 0 UInt64\n}\n\n$TOKEN_PRIVILEGES = struct $Module TokenPrivileges @{\n    PrivilegeCount  = field 0 UInt32\n    Privileges      = field 1 $LUID_AND_ATTRIBUTES.MakeArrayType() -MarshalAs @('ByValArray', 50)\n}\n\n$TOKEN_USER = struct $Module TOKEN_USER @{\n    User            = field 0 $SID_AND_ATTRIBUTES\n}\n\n$FunctionDefinitions = @(\n    (func kernel32 CloseHandle ([bool]) @(\n        [IntPtr]                                  #_In_ HANDLE hObject\n    ) -SetLastError),\n    (func advapi32 ConvertSidToStringSid ([bool]) @(\n        [IntPtr]                                  #_In_  PSID   Sid,\n        [IntPtr].MakeByRefType()                  #_Out_ LPTSTR *StringSid\n    ) -SetLastError),  \n    (func kernel32 CreateToolhelp32Snapshot ([IntPtr]) @(\n        [UInt32],                                 #_In_ DWORD dwFlags,\n        [UInt32]                                  #_In_ DWORD th32ProcessID\n    ) -SetLastError), \n    (func advapi32 GetTokenInformation ([bool]) @(\n      [IntPtr],                                   #_In_      HANDLE                  TokenHandle\n      [Int32],                                    #_In_      TOKEN_INFORMATION_CLASS TokenInformationClass\n      [IntPtr],                                   #_Out_opt_ LPVOID                  TokenInformation\n      [UInt32],                                   #_In_      DWORD                   TokenInformationLength\n      [UInt32].MakeByRefType()                    #_Out_     PDWORD                  ReturnLength\n    ) -SetLastError),\n    (func ntdll NtQueryInformationThread ([UInt32]) @(\n        [IntPtr],                                 #_In_      HANDLE          ThreadHandle,\n        [Int32],                                  #_In_      THREADINFOCLASS ThreadInformationClass,\n        [IntPtr],                                 #_Inout_   PVOID           ThreadInformation,\n        [Int32],                                  #_In_      ULONG           ThreadInformationLength,\n        [IntPtr]                                  #_Out_opt_ PULONG          ReturnLength\n    )),\n    (func kernel32 OpenProcess ([IntPtr]) @(\n        [UInt32],                                 #_In_ DWORD dwDesiredAccess,\n        [bool],                                   #_In_ BOOL  bInheritHandle,\n        [UInt32]                                  #_In_ DWORD dwProcessId\n    ) -SetLastError),    \n    (func advapi32 OpenProcessToken ([bool]) @(\n      [IntPtr],                                   #_In_  HANDLE  ProcessHandle\n      [UInt32],                                   #_In_  DWORD   DesiredAccess\n      [IntPtr].MakeByRefType()                    #_Out_ PHANDLE TokenHandle\n    ) -SetLastError),\n    (func kernel32 OpenThread ([IntPtr]) @(\n        [UInt32],                                  #_In_ DWORD dwDesiredAccess,\n        [bool],                                    #_In_ BOOL  bInheritHandle,\n        [UInt32]                                   #_In_ DWORD dwThreadId\n    ) -SetLastError),    \n    (func advapi32 OpenThreadToken ([bool]) @(\n      [IntPtr],                                    #_In_  HANDLE  ThreadHandle\n      [UInt32],                                    #_In_  DWORD   DesiredAccess\n      [bool],                                      #_In_  BOOL    OpenAsSelf\n      [IntPtr].MakeByRefType()                     #_Out_ PHANDLE TokenHandle\n    ) -SetLastError),    \n    (func kernel32 QueryFullProcessImageName ([bool]) @(\n      [IntPtr]                                     #_In_    HANDLE hProcess\n      [UInt32]                                     #_In_    DWORD  dwFlags,\n      [System.Text.StringBuilder]                  #_Out_   LPTSTR lpExeName,\n      [UInt32].MakeByRefType()                     #_Inout_ PDWORD lpdwSize\n    ) -SetLastError),   \n    (func kernel32 ReadProcessMemory ([Bool]) @(\n        [IntPtr],                                  # _In_ HANDLE hProcess\n        [IntPtr],                                  # _In_ LPCVOID lpBaseAddress\n        [Byte[]],                                  # _Out_ LPVOID  lpBuffer\n        [Int],                                     # _In_ SIZE_T nSize\n        [Int].MakeByRefType()                      # _Out_ SIZE_T *lpNumberOfBytesRead\n    ) -SetLastError),\n    (func kernel32 TerminateThread ([bool]) @(\n        [IntPtr],                                  # _InOut_ HANDLE hThread\n        [UInt32]                                   # _In_ DWORD dwExitCode\n    ) -SetLastError),   \n    (func kernel32 Thread32First ([bool]) @(\n        [IntPtr],                                  #_In_    HANDLE          hSnapshot,\n        $THREADENTRY32.MakeByRefType()             #_Inout_ LPTHREADENTRY32 lpte\n    ) -SetLastError)    \n    (func kernel32 Thread32Next ([bool]) @(\n        [IntPtr],                                  #_In_  HANDLE          hSnapshot,\n        $THREADENTRY32.MakeByRefType()             #_Out_ LPTHREADENTRY32 lpte\n    ) -SetLastError),   \n    (func kernel32 VirtualQueryEx ([Int32]) @(\n        [IntPtr],                                  #_In_     HANDLE                    hProcess,\n        [IntPtr],                                  #_In_opt_ LPCVOID                   lpAddress,\n        $MEMORYBASICINFORMATION.MakeByRefType(),   #_Out_    PMEMORY_BASIC_INFORMATION lpBuffer,\n        [UInt32]                                   #_In_     SIZE_T                    dwLength\n    ) -SetLastError)\n)\n\n$Types = $FunctionDefinitions | Add-Win32Type -Module $Module -Namespace 'Win32SysInfo'\n$Advapi32 = $Types['advapi32']\n$Kernel32 = $Types['kernel32']\n$Ntdll = $Types['ntdll']\n\n$DELETE = 0x00010000\n$READ_CONTROL = 0x00020000\n$SYNCHRONIZE = 0x00100000\n$WRITE_DAC = 0x00040000\n$WRITE_OWNER = 0x00080000\n\n$PROCESS_CREATE_PROCESS = 0x0080\n$PROCESS_CREATE_THREAD = 0x0002\n$PROCESS_DUP_HANDLE = 0x0040\n$PROCESS_QUERY_INFORMATION = 0x0400\n$PROCESS_QUERY_LIMITED_INFORMATION = 0x1000\n$PROCESS_SET_INFORMATION = 0x0200\n$PROCESS_SET_QUOTA = 0x0100\n$PROCESS_SUSPEND_RESUME = 0x0800\n$PROCESS_TERMINATE = 0x0001\n$PROCESS_VM_OPERATION = 0x0008\n$PROCESS_VM_READ = 0x0010\n$PROCESS_VM_WRITE = 0x0020\n$PROCESS_ALL_ACCESS = $DELETE -bor\n                      $READ_CONTROL -bor\n                      $SYNCHRONIZE -bor\n                      $WRITE_DAC -bor\n                      $WRITE_OWNER -bor\n                      $PROCESS_CREATE_PROCESS -bor\n                      $PROCESS_CREATE_THREAD -bor\n                      $PROCESS_DUP_HANDLE -bor\n                      $PROCESS_QUERY_INFORMATION -bor\n                      $PROCESS_QUERY_LIMITED_INFORMATION -bor\n                      $PROCESS_SET_INFORMATION -bor\n                      $PROCESS_SET_QUOTA -bor\n                      $PROCESS_SUSPEND_RESUME -bor\n                      $PROCESS_TERMINATE -bor\n                      $PROCESS_VM_OPERATION -bor\n                      $PROCESS_VM_READ -bor\n                      $PROCESS_VM_WRITE\n\n$THREAD_DIRECT_IMPERSONATION = 0x0200\n$THREAD_GET_CONTEXT = 0x0008\n$THREAD_IMPERSONATE = 0x0100\n$THREAD_QUERY_INFORMATION = 0x0040\n$THREAD_QUERY_LIMITED_INFORMATION = 0x0800\n$THREAD_SET_CONTEXT = 0x0010\n$THREAD_SET_INFORMATION = 0x0020\n$THREAD_SET_LIMITED_INFORMATION = 0x0400\n$THREAD_SET_THREAD_TOKEN = 0x0080\n$THREAD_SUSPEND_RESUME = 0x0002\n$THREAD_TERMINATE = 0x0001\n$THREAD_ALL_ACCESS = $DELETE -bor\n                     $READ_CONTROL -bor\n                     $SYNCHRONIZE -bor\n                     $WRITE_DAC -bor\n                     $WRITE_OWNER -bor\n                     $THREAD_DIRECT_IMPERSONATION -bor\n                     $THREAD_GET_CONTEXT -bor\n                     $THREAD_IMPERSONATE -bor\n                     $THREAD_QUERY_INFORMATION -bor\n                     $THREAD_QUERY_LIMITED_INFORMATION -bor\n                     $THREAD_SET_CONTEXT -bor\n                     $THREAD_SET_LIMITED_INFORMATION -bor\n                     $THREAD_SET_THREAD_TOKEN -bor\n                     $THREAD_SUSPEND_RESUME -bor\n                     $THREAD_TERMINATE\n\n$STANDARD_RIGHTS_REQUIRED = 0x000F0000\n$TOKEN_ASSIGN_PRIMARY = 0x0001\n$TOKEN_DUPLICATE = 0x0002\n$TOKEN_IMPERSONATE = 0x0004\n$TOKEN_QUERY = 0x0008\n$TOKEN_QUERY_SOURCE = 0x0010\n$TOKEN_ADJUST_PRIVILEGES = 0x0020\n$TOKEN_ADJUST_GROUPS = 0x0040\n$TOKEN_ADJUST_DEFAULT = 0x0080\n$TOKEN_ADJUST_SESSIONID = 0x0100\n$TOKEN_ALL_ACCESS = $STANDARD_RIGHTS_REQUIRED -bor \n                    $TOKEN_ASSIGN_PRIMARY -bor\n                    $TOKEN_DUPLICATE -bor\n                    $TOKEN_IMPERSONATE -bor\n                    $TOKEN_QUERY -bor\n                    $TOKEN_QUERY_SOURCE -bor\n                    $TOKEN_ADJUST_PRIVILEGES -bor\n                    $TOKEN_ADJUST_GROUPS -bor \n                    $TOKEN_ADJUST_DEFAULT\n                    \n                    \n$UNTRUSTED_MANDATORY_LEVEL = \"S-1-16-0\"\n$LOW_MANDATORY_LEVEL = \"S-1-16-4096\"\n$MEDIUM_MANDATORY_LEVEL = \"S-1-16-8192\"\n$MEDIUM_PLUS_MANDATORY_LEVEL = \"S-1-16-8448\"\n$HIGH_MANDATORY_LEVEL = \"S-1-16-12288\"\n$SYSTEM_MANDATORY_LEVEL = \"S-1-16-16384\"\n$PROTECTED_PROCESS_MANDATORY_LEVEL = \"S-1-16-20480\"\n$SECURE_PROCESS_MANDATORY_LEVEL = \"S-1-16-28672\"\n\n#endregion PSReflect Definitions (Thread)\n\n#region Win32 API Abstractions\n\nfunction CloseHandle\n{\n    <#\n    .SYNOPSIS\n\n    Closes an open object handle.\n\n    .DESCRIPTION\n\n    The CloseHandle function closes handles to the following objects:\n    - Access token\n    - Communications device\n    - Console input\n    - Console screen buffer\n    - Event\n    - File\n    - File mapping\n    - I/O completion port\n    - Job\n    - Mailslot\n    - Memory resource notification\n    - Mutex\n    - Named pipe\n    - Pipe\n    - Process\n    - Semaphore\n    - Thread\n    - Transaction\n    - Waitable timer\n    \n    The documentation for the functions that create these objects indicates that CloseHandle should be used when you are finished with the object, and what happens to pending operations on the object after the handle is closed. In general, CloseHandle invalidates the specified object handle, decrements the object's handle count, and performs object retention checks. After the last handle to an object is closed, the object is removed from the system. \n\n    .PARAMETER Handle\n\n    A valid handle to an open object.\n\n    .NOTES\n\n    Author - Jared Atkinson (@jaredcatkinson)\n    \n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/ms724211(v=vs.85).aspx\n\n    .EXAMPLE\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $Handle    \n    )\n    \n    <#\n    (func kernel32 CloseHandle ([bool]) @(\n        [IntPtr]                                  #_In_ HANDLE hObject\n    ) -SetLastError)\n    #>\n    \n    $Success = $Kernel32::CloseHandle($Handle); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n\n    if(-not $Success) \n    {\n        Write-Debug \"Close Handle Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n}\n\nfunction ConvertSidToStringSid\n{\n    <#\n    .SYNOPSIS\n\n    The ConvertSidToStringSid function converts a security identifier (SID) to a string format suitable for display, storage, or transmission.\n\n    .DESCRIPTION\n\n    The ConvertSidToStringSid function uses the standard S-R-I-S-S… format for SID strings.\n    \n    .PARAMETER SidPointer\n\n    A pointer to the SID structure to be converted.\n\n    .NOTES\n\n    Author - Jared Atkinson (@jaredcatkinson)\n    \n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa376399(v=vs.85).aspx\n\n    .EXAMPLE\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $SidPointer    \n    )\n    \n    <#\n    (func advapi32 ConvertSidToStringSid ([bool]) @(\n        [IntPtr]                                  #_In_  PSID   Sid,\n        [IntPtr].MakeByRefType()                  #_Out_ LPTSTR *StringSid\n    ) -SetLastError)\n    #>\n    \n    $StringPtr = [IntPtr]::Zero\n    $Success = $Advapi32::ConvertSidToStringSid($SidPointer, [ref]$StringPtr); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n\n    if(-not $Success) \n    {\n        Write-Debug \"ConvertSidToStringSid Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n    \n    Write-Output ([System.Runtime.InteropServices.Marshal]::PtrToStringAuto($StringPtr))\n}\n\nfunction CreateToolhelp32Snapshot\n{\n    <#\n    .SYNOPSIS\n\n    Takes a snapshot of the specified processes, as well as the heaps, modules, and threads used by these processes.\n\n    .DESCRIPTION\n\n    .PARAMETER ProcessId\n\n    .PARAMETER Flags\n    \n    .NOTES\n\n    Author - Jared Atkinson (@jaredcatkinson)\n    \n    .LINK\n\n    .EXAMPLE\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [UInt32]\n        $ProcessId,\n        \n        [Parameter(Mandatory = $true)]\n        [UInt32]\n        $Flags\n    )\n    \n    <#\n    (func kernel32 CreateToolhelp32Snapshot ([IntPtr]) @(\n        [UInt32],                                 #_In_ DWORD dwFlags,\n        [UInt32]                                  #_In_ DWORD th32ProcessID\n    ) -SetLastError)\n    #>\n    \n    $hSnapshot = $Kernel32::CreateToolhelp32Snapshot($Flags, $ProcessId); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n\n    if(-not $hSnapshot) \n    {\n        Write-Debug \"CreateToolhelp32Snapshot Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n    \n    Write-Output $hSnapshot\n}\n\nfunction GetTokenInformation\n{\n    <#\n    .SYNOPSIS\n\n    .DESCRIPTION\n\n    .PARAMETER TokenHandle\n\n    .PARAMETER TokenInformationClass\n\n    .NOTES\n\n    Author - Jared Atkinson (@jaredcatkinson)\n    \n    .LINK\n\n    .EXAMPLE\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $TokenHandle,\n        \n        [Parameter(Mandatory = $true)]\n        $TokenInformationClass \n    )\n    \n    <# \n    (func advapi32 GetTokenInformation ([bool]) @(\n      [IntPtr],                                   #_In_      HANDLE                  TokenHandle\n      [Int32],                                    #_In_      TOKEN_INFORMATION_CLASS TokenInformationClass\n      [IntPtr],                                   #_Out_opt_ LPVOID                  TokenInformation\n      [UInt32],                                   #_In_      DWORD                   TokenInformationLength\n      [UInt32].MakeByRefType()                    #_Out_     PDWORD                  ReturnLength\n    ) -SetLastError)\n    #>\n    \n    # initial query to determine the necessary buffer size\n    $TokenPtrSize = 0\n    $Success = $Advapi32::GetTokenInformation($TokenHandle, $TokenInformationClass, 0, $TokenPtrSize, [ref]$TokenPtrSize)\n    [IntPtr]$TokenPtr = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($TokenPtrSize)\n    \n    # retrieve the proper buffer value\n    $Success = $Advapi32::GetTokenInformation($TokenHandle, $TokenInformationClass, $TokenPtr, $TokenPtrSize, [ref]$TokenPtrSize); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n    \n    if($Success)\n    {\n        switch($TokenInformationClass)\n        {\n            1 # TokenUser\n            {    \n                $TokenUser = $TokenPtr -as $TOKEN_USER\n                ConvertSidToStringSid -SidPointer $TokenUser.User.Sid\n            }\n            3 # TokenPrivilege\n            {\n                # query the process token with the TOKEN_INFORMATION_CLASS = 3 enum to retrieve a TOKEN_PRIVILEGES structure\n                $TokenPrivileges = $TokenPtr -as $TOKEN_PRIVILEGES\n                \n                $sb = New-Object System.Text.StringBuilder\n                \n                for($i=0; $i -lt $TokenPrivileges.PrivilegeCount; $i++) \n                {\n                    if((($TokenPrivileges.Privileges[$i].Attributes -as $LuidAttributes) -band $LuidAttributes::SE_PRIVILEGE_ENABLED) -eq $LuidAttributes::SE_PRIVILEGE_ENABLED)\n                    {\n                       $sb.Append(\", $($TokenPrivileges.Privileges[$i].Luid.LowPart.ToString())\") | Out-Null  \n                    }\n                }\n                Write-Output $sb.ToString().TrimStart(', ')\n            }\n            17 # TokenOrigin\n            {\n                $TokenOrigin = $TokenPtr -as $LUID\n                Write-Output (Get-LogonSession -LogonId $TokenOrigin.LowPart)\n            }\n            22 # TokenAccessInformation\n            {\n            \n            }\n            25 # TokenIntegrityLevel\n            {\n                $TokenIntegrity = $TokenPtr -as $TOKEN_MANDATORY_LABEL\n                switch(ConvertSidToStringSid -SidPointer $TokenIntegrity.Label.Sid)\n                {\n                    $UNTRUSTED_MANDATORY_LEVEL\n                    {\n                        Write-Output \"UNTRUSTED_MANDATORY_LEVEL\"\n                    }\n                    $LOW_MANDATORY_LEVEL\n                    {\n                        Write-Output \"LOW_MANDATORY_LEVEL\"\n                    }\n                    $MEDIUM_MANDATORY_LEVEL\n                    {\n                        Write-Output \"MEDIUM_MANDATORY_LEVEL\"\n                    }\n                    $MEDIUM_PLUS_MANDATORY_LEVEL\n                    {\n                        Write-Output \"MEDIUM_PLUS_MANDATORY_LEVEL\"\n                    }\n                    $HIGH_MANDATORY_LEVEL\n                    {\n                        Write-Output \"HIGH_MANDATORY_LEVEL\"\n                    }\n                    $SYSTEM_MANDATORY_LEVEL\n                    {\n                        Write-Output \"SYSTEM_MANDATORY_LEVEL\"\n                    }\n                    $PROTECTED_PROCESS_MANDATORY_LEVEL\n                    {\n                        Write-Output \"PROTECTED_PROCESS_MANDATORY_LEVEL\"\n                    }\n                    $SECURE_PROCESS_MANDATORY_LEVEL\n                    {\n                        Write-Output \"SECURE_PROCESS_MANDATORY_LEVEL\"\n                    }\n                }\n            }\n        }\n    }\n    else\n    {\n        Write-Debug \"GetTokenInformation Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }        \n    try\n    {\n        [System.Runtime.InteropServices.Marshal]::FreeHGlobal($TokenPtr)\n    }\n    catch\n    {\n    \n    }\n}\n\nfunction NtQueryInformationThread\n{\n    <#\n    .SYNOPSIS\n\n    Retrieves information about the specified thread.\n\n    .DESCRIPTION\n\n    .PARAMETER ThreadHandle\n\n    .NOTES\n\n    Author - Jared Atkinson (@jaredcatkinson)\n    \n    .LINK\n\n    .EXAMPLE\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $ThreadHandle  \n    )\n    \n    <#\n    (func ntdll NtQueryInformationThread ([Int32]) @(\n        [IntPtr],                                 #_In_      HANDLE          ThreadHandle,\n        [Int32],                                  #_In_      THREADINFOCLASS ThreadInformationClass,\n        [IntPtr],                                 #_Inout_   PVOID           ThreadInformation,\n        [Int32],                                  #_In_      ULONG           ThreadInformationLength,\n        [IntPtr]                                  #_Out_opt_ PULONG          ReturnLength\n    ))\n    #>\n    \n    $buf = [System.Runtime.InteropServices.Marshal]::AllocHGlobal([IntPtr]::Size)\n\n    $Success = $Ntdll::NtQueryInformationThread($ThreadHandle, 9, $buf, [IntPtr]::Size, [IntPtr]::Zero); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n\n    if(-not $Success) \n    {\n        Write-Debug \"NtQueryInformationThread Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n    \n    Write-Output ([System.Runtime.InteropServices.Marshal]::ReadIntPtr($buf))\n}\n\nfunction OpenProcess\n{\n    <#\n    .SYNOPSIS\n\n    Opens an existing local process object.\n\n    .DESCRIPTION\n\n    To open a handle to another local process and obtain full access rights, you must enable the SeDebugPrivilege privilege.\n    The handle returned by the OpenProcess function can be used in any function that requires a handle to a process, such as the wait functions, provided the appropriate access rights were requested.\n    When you are finished with the handle, be sure to close it using the CloseHandle function.\n\n    .PARAMETER ProcessId\n\n    The identifier of the local process to be opened.\n    If the specified process is the System Process (0x00000000), the function fails and the last error code is ERROR_INVALID_PARAMETER. If the specified process is the Idle process or one of the CSRSS processes, this function fails and the last error code is ERROR_ACCESS_DENIED because their access restrictions prevent user-level code from opening them.\n\n    .PARAMETER DesiredAccess\n\n    The access to the process object. This access right is checked against the security descriptor for the process. This parameter can be one or more of the process access rights.\n    If the caller has enabled the SeDebugPrivilege privilege, the requested access is granted regardless of the contents of the security descriptor.\n\n    .PARAMETER InheritHandle\n\n    If this value is TRUE, processes created by this process will inherit the handle. Otherwise, the processes do not inherit this handle.\n\n    .NOTES\n    \n    Author - Jared Atkinson (@jaredcatkinson)\n    \n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/ms684320(v=vs.85).aspx\n    \n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/ms684880(v=vs.85).aspx\n\n    .EXAMPLE\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [UInt32]\n        $ProcessId,\n        \n        [Parameter(Mandatory = $true)]\n        [UInt32]\n        $DesiredAccess,\n        \n        [Parameter()]\n        [bool]\n        $InheritHandle = $false\n    )\n    \n    <#\n    (func kernel32 OpenProcess ([IntPtr]) @(\n        [UInt32],                                 #_In_ DWORD dwDesiredAccess,\n        [bool],                                   #_In_ BOOL  bInheritHandle,\n        [UInt32]                                  #_In_ DWORD dwProcessId\n    ) -SetLastError)\n    #>\n    \n    $hProcess = $Kernel32::OpenProcess($DesiredAccess, $InheritHandle, $ProcessId); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n\n    if($hProcess -eq 0) \n    {\n        Write-Debug \"OpenProcess Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n    \n    Write-Output $hProcess\n}\n\nfunction OpenProcessToken\n{ \n    <#\n    .SYNOPSIS\n\n    The OpenProcessToken function opens the access token associated with a process.\n\n    .PARAMETER ProcessHandle\n\n    A handle to the process whose access token is opened. The process must have the PROCESS_QUERY_INFORMATION access permission.\n\n    .PARAMETER DesiredAccess\n\n    Specifies an access mask that specifies the requested types of access to the access token. These requested access types are compared with the discretionary access control list (DACL) of the token to determine which accesses are granted or denied.\n    For a list of access rights for access tokens, see Access Rights for Access-Token Objects.\n\n    .NOTES\n    \n    Author - Jared Atkinson (@jaredcatkinson)\n    \n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa379295(v=vs.85).aspx\n    \n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa374905(v=vs.85).aspx\n\n    .EXAMPLE\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $ProcessHandle,\n        \n        [Parameter(Mandatory = $true)]\n        [UInt32]\n        $DesiredAccess  \n    )\n    \n    <#   \n    (func advapi32 OpenProcessToken ([bool]) @(\n      [IntPtr],                                   #_In_  HANDLE  ProcessHandle\n      [UInt32],                                   #_In_  DWORD   DesiredAccess\n      [IntPtr].MakeByRefType()                    #_Out_ PHANDLE TokenHandle\n    ) -SetLastError)\n    #>\n    \n    $hToken = [IntPtr]::Zero\n    $Success = $Advapi32::OpenProcessToken($ProcessHandle, $DesiredAccess, [ref]$hToken); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n\n    if(-not $Success) \n    {\n        Write-Debug \"OpenProcessToken Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n    \n    Write-Output $hToken\n}\n\nfunction OpenThread\n{\n    <#\n    .SYNOPSIS\n\n    Opens an existing thread object.\n\n    .DESCRIPTION\n\n    The handle returned by OpenThread can be used in any function that requires a handle to a thread, such as the wait functions, provided you requested the appropriate access rights. The handle is granted access to the thread object only to the extent it was specified in the dwDesiredAccess parameter.\n    When you are finished with the handle, be sure to close it by using the CloseHandle function.\n\n    .PARAMETER ThreadId\n\n    The identifier of the thread to be opened.\n\n    .PARAMETER DesiredAccess\n\n    The access to the thread object. This access right is checked against the security descriptor for the thread. This parameter can be one or more of the thread access rights.\n    If the caller has enabled the SeDebugPrivilege privilege, the requested access is granted regardless of the contents of the security descriptor.\n\n    .PARAMETER InheritHandle\n\n    If this value is TRUE, processes created by this process will inherit the handle. Otherwise, the processes do not inherit this handle.\n    \n    .NOTES\n    \n    Author - Jared Atkinson (@jaredcatkinson)\n    \n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/ms684335(v=vs.85).aspx\n    \n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/ms686769(v=vs.85).aspx\n\n    .EXAMPLE\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [UInt32]\n        $ThreadId,\n        \n        [Parameter(Mandatory = $true)]\n        [UInt32]\n        $DesiredAccess,\n        \n        [Parameter()]\n        [bool]\n        $InheritHandle = $false\n    )\n    \n    <#\n    (func kernel32 OpenThread ([IntPtr]) @(\n        [UInt32],                                  #_In_ DWORD dwDesiredAccess,\n        [bool],                                    #_In_ BOOL  bInheritHandle,\n        [UInt32]                                   #_In_ DWORD dwThreadId\n    ) -SetLastError)\n    #>\n    \n    $hThread = $Kernel32::OpenThread($DesiredAccess, $InheritHandle, $ThreadId); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n\n    if($hThread -eq 0) \n    {\n        Write-Debug \"OpenThread Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n    \n    Write-Output $hThread\n}\n\nfunction OpenThreadToken\n{\n    <#\n    .SYNOPSIS\n\n    The OpenThreadToken function opens the access token associated with a thread\n\n    .DESCRIPTION\n\n    Tokens with the anonymous impersonation level cannot be opened.\n    Close the access token handle returned through the Handle parameter by calling CloseHandle.\n\n    .PARAMETER ThreadHandle\n\n    A handle to the thread whose access token is opened.\n\n    .PARAMETER DesiredAccess\n\n    Specifies an access mask that specifies the requested types of access to the access token. These requested access types are reconciled against the token's discretionary access control list (DACL) to determine which accesses are granted or denied.\n\n    .PARAMETER OpenAsSelf\n\n    TRUE if the access check is to be made against the process-level security context.\n    FALSE if the access check is to be made against the current security context of the thread calling the OpenThreadToken function.\n    The OpenAsSelf parameter allows the caller of this function to open the access token of a specified thread when the caller is impersonating a token at SecurityIdentification level. Without this parameter, the calling thread cannot open the access token on the specified thread because it is impossible to open executive-level objects by using the SecurityIdentification impersonation level.\n\n    .NOTES\n    \n    Author - Jared Atkinson (@jaredcatkinson)\n    \n    .LINK\n    \n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa379296(v=vs.85).aspx\n    \n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa374905(v=vs.85).aspx\n\n    .EXAMPLE\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $ThreadHandle,\n        \n        [Parameter(Mandatory = $true)]\n        [UInt32]\n        $DesiredAccess,\n        \n        [Parameter()]\n        [bool]\n        $OpenAsSelf = $false   \n    )\n    \n    <# \n    (func advapi32 OpenThreadToken ([bool]) @(\n      [IntPtr],                                    #_In_  HANDLE  ThreadHandle\n      [UInt32],                                    #_In_  DWORD   DesiredAccess\n      [bool],                                      #_In_  BOOL    OpenAsSelf\n      [IntPtr].MakeByRefType()                     #_Out_ PHANDLE TokenHandle\n    ) -SetLastError)\n    #>\n    \n    $hToken = [IntPtr]::Zero\n    $Success = $Advapi32::OpenThreadToken($ThreadHandle, $DesiredAccess, $OpenAsSelf, [ref]$hToken); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n\n    if(-not $Success) \n    {\n        Write-Debug \"OpenThreadToken Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n        throw \"OpenThreadToken Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n    \n    Write-Output $hToken\n}\n\nfunction QueryFullProcessImageName\n{\n    <#\n    .SYNOPSIS\n\n    Retrieves the full name of the executable image for the specified process.\n\n    .PARAMETER ProcessHandle\n\n    A handle to the process. This handle must be created with the PROCESS_QUERY_INFORMATION or PROCESS_QUERY_LIMITED_INFORMATION access right.\n\n    .PARAMETER Flags\n\n    This parameter can be one of the following values.\n    0x00 - The name should use the Win32 path format.\n    0x01 - The name should use the native system path format.\n\n    .NOTES\n    \n    Author - Jared Atkinson (@jaredcatkinson)\n    \n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/ms684919(v=vs.85).aspx\n\n    .EXAMPLE\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $ProcessHandle,\n        \n        [Parameter()]\n        [UInt32]\n        $Flags = 0\n    )\n    \n    $capacity = 2048\n    $sb = New-Object -TypeName System.Text.StringBuilder($capacity)\n\n    $Success = $Kernel32::QueryFullProcessImageName($ProcessHandle, $Flags, $sb, [ref]$capacity); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n\n    if(-not $Success) \n    {\n        Write-Debug \"QueryFullProcessImageName Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n    \n    Write-Output $sb.ToString()\n}\n\nfunction ReadProcessMemory\n{\n    <#\n    .SYNOPSIS\n\n    Reads data from an area of memory in a specified process. The entire area to be read must be accessible or the operation fails.\n\n    .DESCRIPTION\n\n    ReadProcessMemory copies the data in the specified address range from the address space of the specified process into the specified buffer of the current process. Any process that has a handle with PROCESS_VM_READ access can call the function.\n\n    The entire area to be read must be accessible, and if it is not accessible, the function fails.\n\n    .PARAMETER ProcessHandle\n\n    A handle to the process with memory that is being read. The handle must have PROCESS_VM_READ access to the process.\n\n    .PARAMETER BaseAddress\n\n    The base address in the specified process from which to read. Before any data transfer occurs, the system verifies that all data in the base address and memory of the specified size is accessible for read access, and if it is not accessible the function fails.\n\n    .PARAMETER Size\n\n    The number of bytes to be read from the specified process.\n\n    .NOTES\n    \n    Author - Jared Atkinson (@jaredcatkinson)\n    \n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/ms680553(v=vs.85).aspx\n    \n    .EXAMPLE\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $ProcessHandle,\n        \n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $BaseAddress,\n        \n        [Parameter(Mandatory = $true)]\n        [Int]\n        $Size    \n    )\n    \n    <#\n    (func kernel32 ReadProcessMemory ([Bool]) @(\n        [IntPtr],                                  # _In_ HANDLE hProcess\n        [IntPtr],                                  # _In_ LPCVOID lpBaseAddress\n        [Byte[]],                                  # _Out_ LPVOID  lpBuffer\n        [Int],                                     # _In_ SIZE_T nSize\n        [Int].MakeByRefType()                      # _Out_ SIZE_T *lpNumberOfBytesRead\n    ) -SetLastError) # MSDN states to call GetLastError if the return value is false. \n    #>\n    \n    $buf = New-Object byte[]($Size)\n    [Int32]$NumberOfBytesRead = 0\n    \n    $Success = $Kernel32::ReadProcessMemory($ProcessHandle, $BaseAddress, $buf, $buf.Length, [ref]$NumberOfBytesRead); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n\n    if(-not $Success) \n    {\n        Write-Debug \"ReadProcessMemory Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n    \n    Write-Output $buf\n}    \n\nfunction TerminateThread\n{\n    <#\n    .SYNOPSIS\n\n    Terminates a thread.\n\n    .DESCRIPTION\n\n    TerminateThread is used to cause a thread to exit. When this occurs, the target thread has no chance to execute any user-mode code. DLLs attached to the thread are not notified that the thread is terminating. The system frees the thread's initial stack.\n\n    .PARAMETER ThreadHandle\n\n    A handle to the thread to be terminated.\n\n    The handle must have the THREAD_TERMINATE access right. \n    \n    .PARAMETER ExitCode\n    \n    The exit code for the thread.\n\n    .NOTES\n    \n    Author - Jared Atkinson (@jaredcatkinson)\n    \n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/ms686717(v=vs.85).aspx\n    \n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/ms686769(v=vs.85).aspx\n\n    .EXAMPLE\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $ThreadHandle,\n        \n        [Parameter()]\n        [UInt32]\n        $ExitCode = 0\n    )\n    \n    <#\n    (func kernel32 TerminateThread ([bool]) @(\n        [IntPtr],                                  # _InOut_ HANDLE hThread\n        [UInt32]                                   # _In_ DWORD dwExitCode\n    ) -SetLastError)\n    #>\n    \n    $Success = $Kernel32::TerminateThread($ThreadHandle, $ExitCode); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n\n    if(-not $Success) \n    {\n        Write-Debug \"TerminateThread Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n}\n\nfunction Thread32First\n{\n    <#\n    .SYNOPSIS\n\n    Retrieves information about the first thread of any process encountered in a system snapshot.\n\n    .PARAMETER SnapshotHandle\n\n    A handle to the snapshot returned from a previous call to the CreateToolhelp32Snapshot function.\n\n    .NOTES\n    \n    Author - Jared Atkinson (@jaredcatkinson)\n    \n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/ms686728(v=vs.85).aspx\n\n    .EXAMPLE\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $SnapshotHandle\n    )\n    \n    <#\n    (func kernel32 Thread32First ([bool]) @(\n        [IntPtr],                                  #_In_    HANDLE          hSnapshot,\n        $THREADENTRY32.MakeByRefType()             #_Inout_ LPTHREADENTRY32 lpte\n    ) -SetLastError)\n    #>\n    \n    $Thread = [Activator]::CreateInstance($THREADENTRY32)\n    $Thread.dwSize = $THREADENTRY32::GetSize()\n\n    $Success = $Kernel32::Thread32First($hSnapshot, [Ref]$Thread); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n\n    if(-not $Success) \n    {\n        Write-Debug \"Thread32First Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n    \n    Write-Output $Thread\n}    \n\nfunction VirtualQueryEx\n{\n    <#\n    .SYNOPSIS\n\n    Retrieves information about a range of pages within the virtual address space of a specified process.\n\n    .PARAMETER ProcessHandle\n\n    A handle to the process whose memory information is queried. The handle must have been opened with the PROCESS_QUERY_INFORMATION access right, which enables using the handle to read information from the process object.\n\n    .PARAMETER BaseAddress\n\n    The base address of the region of pages to be queried. This value is rounded down to the next page boundary.\n    \n    .NOTES\n    \n    Author - Jared Atkinson (@jaredcatkinson)\n    \n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa366907(v=vs.85).aspx\n\n    .EXAMPLE\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $ProcessHandle,\n        \n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $BaseAddress\n    )\n    \n    <#  \n    (func kernel32 VirtualQueryEx ([Int32]) @(\n        [IntPtr],                                  #_In_     HANDLE                    hProcess,\n        [IntPtr],                                  #_In_opt_ LPCVOID                   lpAddress,\n        $MEMORYBASICINFORMATION.MakeByRefType(),   #_Out_    PMEMORY_BASIC_INFORMATION lpBuffer,\n        [UInt32]                                   #_In_     SIZE_T                    dwLength\n    ) -SetLastError)\n    #>\n    \n    $memory_basic_info = [Activator]::CreateInstance($MEMORYBASICINFORMATION)\n    $Success = $Kernel32::VirtualQueryEx($ProcessHandle, $BaseAddress, [Ref]$memory_basic_info, $MEMORYBASICINFORMATION::GetSize()); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n\n    if(-not $Success) \n    {\n        Write-Debug \"VirtualQueryEx Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n        #Write-Host \"ProcessHandle: $($ProcessHandle)\"\n        #Write-Host \"BaseAddress: $($BaseAddress)\"\n    }\n    \n    Write-Output $memory_basic_info\n}\n\n#endregion Win32 API Abstractions\n\nStart-AceScript -Uri https://10.182.18.200 -SweepId $args[0] -ScanId ([Guid]::NewGuid()) -RoutingKey siem -Thumbprint 8D1DB3B7B85B6F9E9DE87B291DF66692A10240AE"
  },
  {
    "path": "ACE-Management/PS-ACE/Scripts/ACE_Get-KerberosTicketCache.ps1",
    "content": "﻿function Start-AceScript\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $SweepId,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $ScanId,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $RoutingKey,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Thumbprint\n    )\n\n    $HostFQDN = Get-WmiObject Win32_ComputerSystem -Property 'Name','Domain' | ForEach-Object {\"$($_.Name).$($_.Domain)\"}\n    $ResultDate = (Get-Date).ToString(\"yyyyMMddThhmmssmsmsZ\")\n\n    $dataList = New-Object -TypeName System.Collections.Generic.List['string']\n\n    foreach($o in (Get-KerberosTicketCache))\n    {\n        $o.Add('ComputerName', $HostFQDN)\n        $o.Add('ScanType', 'KerberosTicket')\n        $o.Add('SweepId', $SweepId)\n        $o.Add('ScanId', $ScanId)\n        $o.Add('ResultDate', $ResultDate)\n\n        $message = ConvertTo-JsonV2 -InputObject $o\n        $dataList.Add($message)\n    }\n\n    $props = @{\n        ComputerName = $HostFQDN\n        ScanType     = 'KerberosTicket'\n        RoutingKey   = $RoutingKey\n        ResultDate   = $ResultDate\n        ScanId       = $ScanId\n        Data         = $dataList.ToArray()\n    }\n\n    $body = (ConvertTo-JsonV2 -InputObject $props)\n    \n    #Write-Output $body\n    \n    Invoke-AceWebRequest -Thumbprint $Thumbprint -Uri \"$($Uri)/ace/result/$($SweepId)\" -Body $body\n}\n\nfunction ConvertTo-JsonV2 \n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        $InputObject\n    )\n\n    Begin \n    {\n        $null = [System.Reflection.Assembly]::LoadWithPartialName(\"System.Web.Extensions\")\n        $Serializer = New-Object System.Web.Script.Serialization.JavaScriptSerializer\n    }\n\n    Process \n    {\n        try \n        {\n            $Serializer.Serialize($InputObject)\n        } \n        catch \n        {\n            Write-Error $_\n        }    \n    }\n}\n\nfunction Invoke-AceWebRequest\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Thumbprint,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Body\n    )\n\n    [Net.ServicePointManager]::ServerCertificateValidationCallback = {\n        $Thumbprint = $Thumbprint\n        $certificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]$args[1]\n    \n        if ($certificate -eq $null)\n        {\n            $Host.UI.WriteErrorLine(\"Null certificate.\")\n            return $true\n        }\n    \n        if ($certificate.Thumbprint -eq $Thumbprint)\n        {\n            return $true\n        }\n        else\n        {\n            $Host.UI.WriteErrorLine(\"Thumbprint mismatch. Certificate thumbprint $($certificate.Thumbprint)\")\n        }\n    \n        return $false\n    }\n\n    try\n    {\n        Write-Host \"URI: $($Uri)\"\n\n        # Create web request\n        $WebRequest = [Net.WebRequest]::Create($uri)\n        $WebRequest.Method = 'Post'\n        $WebRequest.ContentType = 'application/json'\n        $WebRequest.Headers.Add('X-API-Version:1.0')\n\n        $byteArray = [System.Text.Encoding]::UTF8.GetBytes($Body)\n        $Webrequest.ContentLength = $byteArray.Length\n        \n        $dataStream = $Webrequest.GetRequestStream()            \n        $dataStream.Write($byteArray, 0, $byteArray.Length)\n        $dataStream.Close()\n\n        # Get response stream\n        $ResponseStream = $Webrequest.GetResponse().GetResponseStream()\n    \n        # Create a stream reader and read the stream returning the string value.\n        $StreamReader = New-Object System.IO.StreamReader -ArgumentList $ResponseStream\n        $StreamReader.ReadToEnd()\n    }\n    catch\n    {\n        Write-Error \"Failed: $($_.exception.innerexception.message)\"\n    }\n}\n\nfunction Get-KerberosTicketCache\n{\n    <#\n    .SYNOPSIS\n\n    \n    .DESCRIPTION\n\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: None\n    Optional Dependencies: None\n\n    .EXAMPLE\n    \n    #>\n    \n    [CmdletBinding()]\n    param\n    (\n\n    )\n    \n    try\n    {\n        # We need a Handle to LSA to list Kerberos tickets\n        # If we want to look at tickets from a session other than our own\n        # Then we need to use LsaRegisterLogonProcess instead of LsaConnectUntrusted\n        $hLsa = LsaRegisterLogonProcess\n    }\n    catch\n    {\n        # If the original call fails then it is likely we don't have SeTcbPrivilege\n        # To get SeTcbPrivilege we can Impersonate a NT AUTHORITY\\SYSTEM Token\n        Get-System\n            \n        # We should now have the proper privileges to get a Handle to LSA\n        $hLsa = LsaRegisterLogonProcess\n\n        # We don't need our NT AUTHORITY\\SYSTEM Token anymore\n        # So we can revert to our original token\n        RevertToSelf\n    }\n\n    # Enumerate all Logon Sessions\n    # We need the sessions' LogonIds to enumerate it\n    $Sessions = Get-LogonSession\n\n    foreach($Session in $Sessions)\n    {\n        try\n        {\n            # Get the tickets from the LSA provider\n            $ticket = LsaCallAuthenticationPackage -LsaHandle $hLsa -AuthenticationPackageName MICROSOFT_KERBEROS_NAME_A -LogonId $Session.LogonId \n            \n            if($ticket -ne $null)\n            {\n                # Add properties from the Logon Session to the ticket\n                foreach($t in $ticket)\n                {\n                    $t.Add('SessionLogonId', $Session.LogonId)\n                    $t.Add('SessionUserName', $Session.UserName)\n                    $t.Add('SessionLogonDomain', $Session.LogonDomain)\n                    $t.Add('SessionAuthenticationPackage', $Session.AuthenticationPackage)\n                    $t.Add('SessionSid', $Session.Sid.ToString())\n                    $t.Add('SessionLogonType', $Session.LogonType)\n                    $t.Add('SessionUserPrincipalName', $Session.Upn)\n                }\n\n\n                # Output the ticket\n                Write-Output $ticket\n            }\n        }\n        catch\n        {\n\n        }\n    }\n\n    # Cleanup our LSA Handle\n    LsaDeregisterLogonProcess -LsaHandle $hLsa\n}\n\n#region Helper Functions\nfunction Get-LogonSession\n{\n    <#\n    .SYNOPSIS\n\n    .DESCRIPTION\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: None\n    Optional Dependencies: None\n\n    .LINK\n\n    .EXAMPLE\n    #>\n\n    [CmdletBinding()]\n    param\n    (\n\n    )\n\n    $SessionCount, $LuidPtr = LsaEnumerateLogonSessions\n    $Sessions = LsaGetLogonSessionData -LuidPtr $LuidPtr -SessionCount $SessionCount\n\n    Write-Output $Sessions\n}\n\nfunction Get-System\n{\n    <#\n    .SYNOPSIS\n\n    .DESCRIPTION\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: None\n    Optional Dependencies: None\n        \n    .LINK\n\n    .EXAMPLE\n    #>\n\n    # Get a Process object for the winlogon process\n    # The System.Diagnostics.Process class has a handle property that we can use\n    # We know winlogon will be available and is running as NT AUTHORITY\\SYSTEM\n    $winlogons = Get-Process -Name winlogon\n\n    try\n    {\n        $proc = $winlogons[0]\n    }\n    catch\n    {\n        $proc = $winlogons\n    }\n\n    # Open winlogon's Token with TOKEN_DUPLICATE Acess\n    # This allows us to make a copy of the token with DuplicateToken\n    $hToken = OpenProcessToken -ProcessHandle $proc.Handle -DesiredAccess $TOKEN_DUPLICATE -Debug\n    \n    # Make a copy of the NT AUTHORITY\\SYSTEM Token\n    $hDupToken = DuplicateToken -TokenHandle $hToken\n    \n    # Apply our Duplicated Token to our Thread\n    ImpersonateLoggedOnUser -TokenHandle $hDupToken\n    \n    # Clean up the handles we created\n    CloseHandle -Handle $hToken\n    CloseHandle -Handle $hDupToken\n\n    if(-not [System.Security.Principal.WindowsIdentity]::GetCurrent().Name -eq 'NT AUTHORITY\\SYSTEM')\n    {\n        throw \"Unable to Impersonate System Token\"\n    }\n}\n#endregion Helper Functions\n\n#region PSReflect\nfunction New-InMemoryModule\n{\n<#\n.SYNOPSIS\n\nCreates an in-memory assembly and module\n\nAuthor: Matthew Graeber (@mattifestation)\nLicense: BSD 3-Clause\nRequired Dependencies: None\nOptional Dependencies: None\n \n.DESCRIPTION\n\nWhen defining custom enums, structs, and unmanaged functions, it is\nnecessary to associate to an assembly module. This helper function\ncreates an in-memory module that can be passed to the 'enum',\n'struct', and Add-Win32Type functions.\n\n.PARAMETER ModuleName\n\nSpecifies the desired name for the in-memory assembly and module. If\nModuleName is not provided, it will default to a GUID.\n\n.EXAMPLE\n\n$Module = New-InMemoryModule -ModuleName Win32\n#>\n\n    Param\n    (\n        [Parameter(Position = 0)]\n        [ValidateNotNullOrEmpty()]\n        [String]\n        $ModuleName = [Guid]::NewGuid().ToString()\n    )\n\n    $AppDomain = [Reflection.Assembly].Assembly.GetType('System.AppDomain').GetProperty('CurrentDomain').GetValue($null, @())\n    $LoadedAssemblies = $AppDomain.GetAssemblies()\n\n    foreach ($Assembly in $LoadedAssemblies) {\n        if ($Assembly.FullName -and ($Assembly.FullName.Split(',')[0] -eq $ModuleName)) {\n            return $Assembly\n        }\n    }\n\n    $DynAssembly = New-Object Reflection.AssemblyName($ModuleName)\n    $Domain = $AppDomain\n    $AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, 'Run')\n    $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule($ModuleName, $False)\n\n    return $ModuleBuilder\n}\n\n# A helper function used to reduce typing while defining function\n# prototypes for Add-Win32Type.\nfunction func\n{\n    Param\n    (\n        [Parameter(Position = 0, Mandatory = $True)]\n        [String]\n        $DllName,\n\n        [Parameter(Position = 1, Mandatory = $True)]\n        [string]\n        $FunctionName,\n\n        [Parameter(Position = 2, Mandatory = $True)]\n        [Type]\n        $ReturnType,\n\n        [Parameter(Position = 3)]\n        [Type[]]\n        $ParameterTypes,\n\n        [Parameter(Position = 4)]\n        [Runtime.InteropServices.CallingConvention]\n        $NativeCallingConvention,\n\n        [Parameter(Position = 5)]\n        [Runtime.InteropServices.CharSet]\n        $Charset,\n\n        [String]\n        $EntryPoint,\n\n        [Switch]\n        $SetLastError\n    )\n\n    $Properties = @{\n        DllName = $DllName\n        FunctionName = $FunctionName\n        ReturnType = $ReturnType\n    }\n\n    if ($ParameterTypes) { $Properties['ParameterTypes'] = $ParameterTypes }\n    if ($NativeCallingConvention) { $Properties['NativeCallingConvention'] = $NativeCallingConvention }\n    if ($Charset) { $Properties['Charset'] = $Charset }\n    if ($SetLastError) { $Properties['SetLastError'] = $SetLastError }\n    if ($EntryPoint) { $Properties['EntryPoint'] = $EntryPoint }\n\n    New-Object PSObject -Property $Properties\n}\n\nfunction Add-Win32Type\n{\n<#\n.SYNOPSIS\n\nCreates a .NET type for an unmanaged Win32 function.\n\nAuthor: Matthew Graeber (@mattifestation)\nLicense: BSD 3-Clause\nRequired Dependencies: None\nOptional Dependencies: func\n \n.DESCRIPTION\n\nAdd-Win32Type enables you to easily interact with unmanaged (i.e.\nWin32 unmanaged) functions in PowerShell. After providing\nAdd-Win32Type with a function signature, a .NET type is created\nusing reflection (i.e. csc.exe is never called like with Add-Type).\n\nThe 'func' helper function can be used to reduce typing when defining\nmultiple function definitions.\n\n.PARAMETER DllName\n\nThe name of the DLL.\n\n.PARAMETER FunctionName\n\nThe name of the target function.\n\n.PARAMETER EntryPoint\n\nThe DLL export function name. This argument should be specified if the\nspecified function name is different than the name of the exported\nfunction.\n\n.PARAMETER ReturnType\n\nThe return type of the function.\n\n.PARAMETER ParameterTypes\n\nThe function parameters.\n\n.PARAMETER NativeCallingConvention\n\nSpecifies the native calling convention of the function. Defaults to\nstdcall.\n\n.PARAMETER Charset\n\nIf you need to explicitly call an 'A' or 'W' Win32 function, you can\nspecify the character set.\n\n.PARAMETER SetLastError\n\nIndicates whether the callee calls the SetLastError Win32 API\nfunction before returning from the attributed method.\n\n.PARAMETER Module\n\nThe in-memory module that will host the functions. Use\nNew-InMemoryModule to define an in-memory module.\n\n.PARAMETER Namespace\n\nAn optional namespace to prepend to the type. Add-Win32Type defaults\nto a namespace consisting only of the name of the DLL.\n\n.EXAMPLE\n\n$Mod = New-InMemoryModule -ModuleName Win32\n\n$FunctionDefinitions = @(\n    (func kernel32 GetProcAddress ([IntPtr]) @([IntPtr], [String]) -Charset Ansi -SetLastError),\n    (func kernel32 GetModuleHandle ([Intptr]) @([String]) -SetLastError),\n    (func ntdll RtlGetCurrentPeb ([IntPtr]) @())\n)\n\n$Types = $FunctionDefinitions | Add-Win32Type -Module $Mod -Namespace 'Win32'\n$Kernel32 = $Types['kernel32']\n$Ntdll = $Types['ntdll']\n$Ntdll::RtlGetCurrentPeb()\n$ntdllbase = $Kernel32::GetModuleHandle('ntdll')\n$Kernel32::GetProcAddress($ntdllbase, 'RtlGetCurrentPeb')\n\n.NOTES\n\nInspired by Lee Holmes' Invoke-WindowsApi http://poshcode.org/2189\n\nWhen defining multiple function prototypes, it is ideal to provide\nAdd-Win32Type with an array of function signatures. That way, they\nare all incorporated into the same in-memory module.\n#>\n\n    [OutputType([Hashtable])]\n    Param(\n        [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)]\n        [String]\n        $DllName,\n\n        [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)]\n        [String]\n        $FunctionName,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [String]\n        $EntryPoint,\n\n        [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)]\n        [Type]\n        $ReturnType,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [Type[]]\n        $ParameterTypes,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [Runtime.InteropServices.CallingConvention]\n        $NativeCallingConvention = [Runtime.InteropServices.CallingConvention]::StdCall,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [Runtime.InteropServices.CharSet]\n        $Charset = [Runtime.InteropServices.CharSet]::Auto,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [Switch]\n        $SetLastError,\n\n        [Parameter(Mandatory = $True)]\n        [ValidateScript({($_ -is [Reflection.Emit.ModuleBuilder]) -or ($_ -is [Reflection.Assembly])})]\n        $Module,\n\n        [ValidateNotNull()]\n        [String]\n        $Namespace = ''\n    )\n\n    BEGIN\n    {\n        $TypeHash = @{}\n    }\n\n    PROCESS\n    {\n        if ($Module -is [Reflection.Assembly])\n        {\n            if ($Namespace)\n            {\n                $TypeHash[$DllName] = $Module.GetType(\"$Namespace.$DllName\")\n            }\n            else\n            {\n                $TypeHash[$DllName] = $Module.GetType($DllName)\n            }\n        }\n        else\n        {\n            # Define one type for each DLL\n            if (!$TypeHash.ContainsKey($DllName))\n            {\n                if ($Namespace)\n                {\n                    $TypeHash[$DllName] = $Module.DefineType(\"$Namespace.$DllName\", 'Public,BeforeFieldInit')\n                }\n                else\n                {\n                    $TypeHash[$DllName] = $Module.DefineType($DllName, 'Public,BeforeFieldInit')\n                }\n            }\n\n            $Method = $TypeHash[$DllName].DefineMethod(\n                $FunctionName,\n                'Public,Static,PinvokeImpl',\n                $ReturnType,\n                $ParameterTypes)\n\n            # Make each ByRef parameter an Out parameter\n            $i = 1\n            foreach($Parameter in $ParameterTypes)\n            {\n                if ($Parameter.IsByRef)\n                {\n                    [void] $Method.DefineParameter($i, 'Out', $null)\n                }\n\n                $i++\n            }\n\n            $DllImport = [Runtime.InteropServices.DllImportAttribute]\n            $SetLastErrorField = $DllImport.GetField('SetLastError')\n            $CallingConventionField = $DllImport.GetField('CallingConvention')\n            $CharsetField = $DllImport.GetField('CharSet')\n            $EntryPointField = $DllImport.GetField('EntryPoint')\n            if ($SetLastError) { $SLEValue = $True } else { $SLEValue = $False }\n\n            if ($PSBoundParameters['EntryPoint']) { $ExportedFuncName = $EntryPoint } else { $ExportedFuncName = $FunctionName }\n\n            # Equivalent to C# version of [DllImport(DllName)]\n            $Constructor = [Runtime.InteropServices.DllImportAttribute].GetConstructor([String])\n            $DllImportAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($Constructor,\n                $DllName, [Reflection.PropertyInfo[]] @(), [Object[]] @(),\n                [Reflection.FieldInfo[]] @($SetLastErrorField,\n                                            $CallingConventionField,\n                                            $CharsetField,\n                                            $EntryPointField),\n                [Object[]] @($SLEValue,\n                                ([Runtime.InteropServices.CallingConvention] $NativeCallingConvention),\n                                ([Runtime.InteropServices.CharSet] $Charset),\n                                $ExportedFuncName))\n\n            $Method.SetCustomAttribute($DllImportAttribute)\n        }\n    }\n\n    END\n    {\n        if ($Module -is [Reflection.Assembly])\n        {\n            return $TypeHash\n        }\n\n        $ReturnTypes = @{}\n\n        foreach ($Key in $TypeHash.Keys)\n        {\n            $Type = $TypeHash[$Key].CreateType()\n            \n            $ReturnTypes[$Key] = $Type\n        }\n\n        return $ReturnTypes\n    }\n}\n\nfunction psenum\n{\n<#\n.SYNOPSIS\n\nCreates an in-memory enumeration for use in your PowerShell session.\n\nAuthor: Matthew Graeber (@mattifestation)\nLicense: BSD 3-Clause\nRequired Dependencies: None\nOptional Dependencies: None\n \n.DESCRIPTION\n\nThe 'psenum' function facilitates the creation of enums entirely in\nmemory using as close to a \"C style\" as PowerShell will allow.\n\n.PARAMETER Module\n\nThe in-memory module that will host the enum. Use\nNew-InMemoryModule to define an in-memory module.\n\n.PARAMETER FullName\n\nThe fully-qualified name of the enum.\n\n.PARAMETER Type\n\nThe type of each enum element.\n\n.PARAMETER EnumElements\n\nA hashtable of enum elements.\n\n.PARAMETER Bitfield\n\nSpecifies that the enum should be treated as a bitfield.\n\n.EXAMPLE\n\n$Mod = New-InMemoryModule -ModuleName Win32\n\n$ImageSubsystem = psenum $Mod PE.IMAGE_SUBSYSTEM UInt16 @{\n    UNKNOWN =                  0\n    NATIVE =                   1 # Image doesn't require a subsystem.\n    WINDOWS_GUI =              2 # Image runs in the Windows GUI subsystem.\n    WINDOWS_CUI =              3 # Image runs in the Windows character subsystem.\n    OS2_CUI =                  5 # Image runs in the OS/2 character subsystem.\n    POSIX_CUI =                7 # Image runs in the Posix character subsystem.\n    NATIVE_WINDOWS =           8 # Image is a native Win9x driver.\n    WINDOWS_CE_GUI =           9 # Image runs in the Windows CE subsystem.\n    EFI_APPLICATION =          10\n    EFI_BOOT_SERVICE_DRIVER =  11\n    EFI_RUNTIME_DRIVER =       12\n    EFI_ROM =                  13\n    XBOX =                     14\n    WINDOWS_BOOT_APPLICATION = 16\n}\n\n.NOTES\n\nPowerShell purists may disagree with the naming of this function but\nagain, this was developed in such a way so as to emulate a \"C style\"\ndefinition as closely as possible. Sorry, I'm not going to name it\nNew-Enum. :P\n#>\n\n    [OutputType([Type])]\n    Param\n    (\n        [Parameter(Position = 0, Mandatory = $True)]\n        [ValidateScript({($_ -is [Reflection.Emit.ModuleBuilder]) -or ($_ -is [Reflection.Assembly])})]\n        $Module,\n\n        [Parameter(Position = 1, Mandatory = $True)]\n        [ValidateNotNullOrEmpty()]\n        [String]\n        $FullName,\n\n        [Parameter(Position = 2, Mandatory = $True)]\n        [Type]\n        $Type,\n\n        [Parameter(Position = 3, Mandatory = $True)]\n        [ValidateNotNullOrEmpty()]\n        [Hashtable]\n        $EnumElements,\n\n        [Switch]\n        $Bitfield\n    )\n\n    if ($Module -is [Reflection.Assembly])\n    {\n        return ($Module.GetType($FullName))\n    }\n\n    $EnumType = $Type -as [Type]\n\n    $EnumBuilder = $Module.DefineEnum($FullName, 'Public', $EnumType)\n\n    if ($Bitfield)\n    {\n        $FlagsConstructor = [FlagsAttribute].GetConstructor(@())\n        $FlagsCustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($FlagsConstructor, @())\n        $EnumBuilder.SetCustomAttribute($FlagsCustomAttribute)\n    }\n\n    foreach ($Key in $EnumElements.Keys)\n    {\n        # Apply the specified enum type to each element\n        $null = $EnumBuilder.DefineLiteral($Key, $EnumElements[$Key] -as $EnumType)\n    }\n\n    $EnumBuilder.CreateType()\n}\n\n# A helper function used to reduce typing while defining struct\n# fields.\nfunction field\n{\n    Param\n    (\n        [Parameter(Position = 0, Mandatory = $True)]\n        [UInt16]\n        $Position,\n        \n        [Parameter(Position = 1, Mandatory = $True)]\n        [Type]\n        $Type,\n        \n        [Parameter(Position = 2)]\n        [UInt16]\n        $Offset,\n        \n        [Object[]]\n        $MarshalAs\n    )\n\n    @{\n        Position = $Position\n        Type = $Type -as [Type]\n        Offset = $Offset\n        MarshalAs = $MarshalAs\n    }\n}\n\nfunction struct\n{\n<#\n.SYNOPSIS\n\nCreates an in-memory struct for use in your PowerShell session.\n\nAuthor: Matthew Graeber (@mattifestation)\nLicense: BSD 3-Clause\nRequired Dependencies: None\nOptional Dependencies: field\n \n.DESCRIPTION\n\nThe 'struct' function facilitates the creation of structs entirely in\nmemory using as close to a \"C style\" as PowerShell will allow. Struct\nfields are specified using a hashtable where each field of the struct\nis comprosed of the order in which it should be defined, its .NET\ntype, and optionally, its offset and special marshaling attributes.\n\nOne of the features of 'struct' is that after your struct is defined,\nit will come with a built-in GetSize method as well as an explicit\nconverter so that you can easily cast an IntPtr to the struct without\nrelying upon calling SizeOf and/or PtrToStructure in the Marshal\nclass.\n\n.PARAMETER Module\n\nThe in-memory module that will host the struct. Use\nNew-InMemoryModule to define an in-memory module.\n\n.PARAMETER FullName\n\nThe fully-qualified name of the struct.\n\n.PARAMETER StructFields\n\nA hashtable of fields. Use the 'field' helper function to ease\ndefining each field.\n\n.PARAMETER PackingSize\n\nSpecifies the memory alignment of fields.\n\n.PARAMETER ExplicitLayout\n\nIndicates that an explicit offset for each field will be specified.\n\n.EXAMPLE\n\n$Mod = New-InMemoryModule -ModuleName Win32\n\n$ImageDosSignature = psenum $Mod PE.IMAGE_DOS_SIGNATURE UInt16 @{\n    DOS_SIGNATURE =    0x5A4D\n    OS2_SIGNATURE =    0x454E\n    OS2_SIGNATURE_LE = 0x454C\n    VXD_SIGNATURE =    0x454C\n}\n\n$ImageDosHeader = struct $Mod PE.IMAGE_DOS_HEADER @{\n    e_magic =    field 0 $ImageDosSignature\n    e_cblp =     field 1 UInt16\n    e_cp =       field 2 UInt16\n    e_crlc =     field 3 UInt16\n    e_cparhdr =  field 4 UInt16\n    e_minalloc = field 5 UInt16\n    e_maxalloc = field 6 UInt16\n    e_ss =       field 7 UInt16\n    e_sp =       field 8 UInt16\n    e_csum =     field 9 UInt16\n    e_ip =       field 10 UInt16\n    e_cs =       field 11 UInt16\n    e_lfarlc =   field 12 UInt16\n    e_ovno =     field 13 UInt16\n    e_res =      field 14 UInt16[] -MarshalAs @('ByValArray', 4)\n    e_oemid =    field 15 UInt16\n    e_oeminfo =  field 16 UInt16\n    e_res2 =     field 17 UInt16[] -MarshalAs @('ByValArray', 10)\n    e_lfanew =   field 18 Int32\n}\n\n# Example of using an explicit layout in order to create a union.\n$TestUnion = struct $Mod TestUnion @{\n    field1 = field 0 UInt32 0\n    field2 = field 1 IntPtr 0\n} -ExplicitLayout\n\n.NOTES\n\nPowerShell purists may disagree with the naming of this function but\nagain, this was developed in such a way so as to emulate a \"C style\"\ndefinition as closely as possible. Sorry, I'm not going to name it\nNew-Struct. :P\n#>\n\n    [OutputType([Type])]\n    Param\n    (\n        [Parameter(Position = 1, Mandatory = $True)]\n        [ValidateScript({($_ -is [Reflection.Emit.ModuleBuilder]) -or ($_ -is [Reflection.Assembly])})]\n        $Module,\n\n        [Parameter(Position = 2, Mandatory = $True)]\n        [ValidateNotNullOrEmpty()]\n        [String]\n        $FullName,\n\n        [Parameter(Position = 3, Mandatory = $True)]\n        [ValidateNotNullOrEmpty()]\n        [Hashtable]\n        $StructFields,\n\n        [Reflection.Emit.PackingSize]\n        $PackingSize = [Reflection.Emit.PackingSize]::Unspecified,\n\n        [Switch]\n        $ExplicitLayout\n    )\n\n    if ($Module -is [Reflection.Assembly])\n    {\n        return ($Module.GetType($FullName))\n    }\n\n    [Reflection.TypeAttributes] $StructAttributes = 'AnsiClass,\n        Class,\n        Public,\n        Sealed,\n        BeforeFieldInit'\n\n    if ($ExplicitLayout)\n    {\n        $StructAttributes = $StructAttributes -bor [Reflection.TypeAttributes]::ExplicitLayout\n    }\n    else\n    {\n        $StructAttributes = $StructAttributes -bor [Reflection.TypeAttributes]::SequentialLayout\n    }\n\n    $StructBuilder = $Module.DefineType($FullName, $StructAttributes, [ValueType], $PackingSize)\n    $ConstructorInfo = [Runtime.InteropServices.MarshalAsAttribute].GetConstructors()[0]\n    $SizeConst = @([Runtime.InteropServices.MarshalAsAttribute].GetField('SizeConst'))\n\n    $Fields = New-Object Hashtable[]($StructFields.Count)\n\n    # Sort each field according to the orders specified\n    # Unfortunately, PSv2 doesn't have the luxury of the\n    # hashtable [Ordered] accelerator.\n    foreach ($Field in $StructFields.Keys)\n    {\n        $Index = $StructFields[$Field]['Position']\n        $Fields[$Index] = @{FieldName = $Field; Properties = $StructFields[$Field]}\n    }\n\n    foreach ($Field in $Fields)\n    {\n        $FieldName = $Field['FieldName']\n        $FieldProp = $Field['Properties']\n\n        $Offset = $FieldProp['Offset']\n        $Type = $FieldProp['Type']\n        $MarshalAs = $FieldProp['MarshalAs']\n\n        $NewField = $StructBuilder.DefineField($FieldName, $Type, 'Public')\n\n        if ($MarshalAs)\n        {\n            $UnmanagedType = $MarshalAs[0] -as ([Runtime.InteropServices.UnmanagedType])\n            if ($MarshalAs[1])\n            {\n                $Size = $MarshalAs[1]\n                $AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($ConstructorInfo,\n                    $UnmanagedType, $SizeConst, @($Size))\n            }\n            else\n            {\n                $AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($ConstructorInfo, [Object[]] @($UnmanagedType))\n            }\n            \n            $NewField.SetCustomAttribute($AttribBuilder)\n        }\n\n        if ($ExplicitLayout) { $NewField.SetOffset($Offset) }\n    }\n\n    # Make the struct aware of its own size.\n    # No more having to call [Runtime.InteropServices.Marshal]::SizeOf!\n    $SizeMethod = $StructBuilder.DefineMethod('GetSize',\n        'Public, Static',\n        [Int],\n        [Type[]] @())\n    $ILGenerator = $SizeMethod.GetILGenerator()\n    # Thanks for the help, Jason Shirk!\n    $ILGenerator.Emit([Reflection.Emit.OpCodes]::Ldtoken, $StructBuilder)\n    $ILGenerator.Emit([Reflection.Emit.OpCodes]::Call,\n        [Type].GetMethod('GetTypeFromHandle'))\n    $ILGenerator.Emit([Reflection.Emit.OpCodes]::Call,\n        [Runtime.InteropServices.Marshal].GetMethod('SizeOf', [Type[]] @([Type])))\n    $ILGenerator.Emit([Reflection.Emit.OpCodes]::Ret)\n\n    # Allow for explicit casting from an IntPtr\n    # No more having to call [Runtime.InteropServices.Marshal]::PtrToStructure!\n    $ImplicitConverter = $StructBuilder.DefineMethod('op_Implicit',\n        'PrivateScope, Public, Static, HideBySig, SpecialName',\n        $StructBuilder,\n        [Type[]] @([IntPtr]))\n    $ILGenerator2 = $ImplicitConverter.GetILGenerator()\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Nop)\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ldarg_0)\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ldtoken, $StructBuilder)\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Call,\n        [Type].GetMethod('GetTypeFromHandle'))\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Call,\n        [Runtime.InteropServices.Marshal].GetMethod('PtrToStructure', [Type[]] @([IntPtr], [Type])))\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Unbox_Any, $StructBuilder)\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ret)\n\n    $StructBuilder.CreateType()\n}\n#endregion PSReflect\n\n$Module = New-InMemoryModule -ModuleName KerberosTicket\n\n#region Constants\n$STANDARD_RIGHTS_REQUIRED = 0x000F0000\n$TOKEN_ASSIGN_PRIMARY = 0x0001\n$TOKEN_DUPLICATE = 0x0002\n$TOKEN_IMPERSONATE = 0x0004\n$TOKEN_QUERY = 0x0008\n$TOKEN_QUERY_SOURCE = 0x0010\n$TOKEN_ADJUST_PRIVILEGES = 0x0020\n$TOKEN_ADJUST_GROUPS = 0x0040\n$TOKEN_ADJUST_DEFAULT = 0x0080\n$TOKEN_ADJUST_SESSIONID = 0x0100\n$TOKEN_ALL_ACCESS = $STANDARD_RIGHTS_REQUIRED -bor \n                    $TOKEN_ASSIGN_PRIMARY -bor\n                    $TOKEN_DUPLICATE -bor\n                    $TOKEN_IMPERSONATE -bor\n                    $TOKEN_QUERY -bor\n                    $TOKEN_QUERY_SOURCE -bor\n                    $TOKEN_ADJUST_PRIVILEGES -bor\n                    $TOKEN_ADJUST_GROUPS -bor \n                    $TOKEN_ADJUST_DEFAULT  \n#endregion Constants\n\n#region Enums\n$KERB_PROTOCOL_MESSAGE_TYPE = psenum $Module KERB_PROTOCOL_MESSAGE_TYPE UInt32 @{ \n    KerbDebugRequestMessage                  = 0\n    KerbQueryTicketCacheMessage              = 1\n    KerbChangeMachinePasswordMessage         = 2\n    KerbVerifyPacMessage                     = 3\n    KerbRetrieveTicketMessage                = 4\n    KerbUpdateAddressesMessage               = 5\n    KerbPurgeTicketCacheMessage              = 6\n    KerbChangePasswordMessage                = 7\n    KerbRetrieveEncodedTicketMessage         = 8\n    KerbDecryptDataMessage                   = 9\n    KerbAddBindingCacheEntryMessage          = 10\n    KerbSetPasswordMessage                   = 11\n    KerbSetPasswordExMessage                 = 12\n    KerbVerifyCredentialsMessage             = 13\n    KerbQueryTicketCacheExMessage            = 14\n    KerbPurgeTicketCacheExMessage            = 15\n    KerbRefreshSmartcardCredentialsMessage   = 16\n    KerbAddExtraCredentialsMessage           = 17\n    KerbQuerySupplementalCredentialsMessage  = 18\n    KerbTransferCredentialsMessage           = 19\n    KerbQueryTicketCacheEx2Message           = 20\n    KerbSubmitTicketMessage                  = 21\n    KerbAddExtraCredentialsExMessage         = 22\n    KerbQueryKdcProxyCacheMessage            = 23\n    KerbPurgeKdcProxyCacheMessage            = 24\n    KerbQueryTicketCacheEx3Message           = 25\n    KerbCleanupMachinePkinitCredsMessage     = 26\n    KerbAddBindingCacheEntryExMessage        = 27\n    KerbQueryBindingCacheMessage             = 28\n    KerbPurgeBindingCacheMessage             = 29\n    KerbQueryDomainExtendedPoliciesMessage   = 30\n    KerbQueryS4U2ProxyCacheMessage           = 31\n}\n\n$KERB_CACHE_OPTIONS = psenum $Module KERB_CACHE_OPTIONS UInt64 @{\n    KERB_RETRIEVE_TICKET_DONT_USE_CACHE = 0x1\n    KERB_RETRIEVE_TICKET_USE_CACHE_ONLY = 0x2\n    KERB_RETRIEVE_TICKET_USE_CREDHANDLE = 0x4\n    KERB_RETRIEVE_TICKET_AS_KERB_CRED   = 0x8\n    KERB_RETRIEVE_TICKET_WITH_SEC_CRED  = 0x10 \n    KERB_RETRIEVE_TICKET_CACHE_TICKET   = 0x20\n    KERB_RETRIEVE_TICKET_MAX_LIFETIME   = 0x40\n} -Bitfield\n\n$KERB_ENCRYPTION_TYPE = psenum $Module KERB_ENCRYPTION_TYPE UInt32 @{\n        reserved0                         = 0\n        des_cbc_crc                       = 1\n        des_cbc_md4                       = 2\n        des_cbc_md5                       = 3\n        reserved1                         = 4\n        des3_cbc_md5                      = 5\n        reserved2                         = 6\n        des3_cbc_sha1                     = 7\n        dsaWithSHA1_CmsOID                = 9\n        md5WithRSAEncryption_CmsOID       = 10\n        sha1WithRSAEncryption_CmsOID      = 11\n        rc2CBC_EnvOID                     = 12\n        rsaEncryption_EnvOID              = 13\n        rsaES_OAEP_ENV_OID                = 14\n        des_ede3_cbc_Env_OID              = 15\n        des3_cbc_sha1_kd                  = 16\n        aes128_cts_hmac_sha1_96           = 17\n        aes256_cts_hmac_sha1_96           = 18\n        aes128_cts_hmac_sha256_128        = 19\n        aes256_cts_hmac_sha384_192        = 20\n        rc4_hmac                          = 23\n        rc4_hmac_exp                      = 24\n        camellia128_cts_cmac              = 25\n        camellia256_cts_cmac              = 26\n        subkey_keymaterial                = 65\n}\n\n$KERB_TICKET_FLAGS = psenum $Module KERB_TICKET_FLAGS UInt32 @{\n    reserved          = 2147483648\n    forwardable       = 0x40000000\n    forwarded         = 0x20000000\n    proxiable         = 0x10000000\n    proxy             = 0x08000000\n    may_postdate      = 0x04000000\n    postdated         = 0x02000000\n    invalid           = 0x01000000\n    renewable         = 0x00800000\n    initial           = 0x00400000\n    pre_authent       = 0x00200000\n    hw_authent        = 0x00100000\n    ok_as_delegate    = 0x00040000\n    name_canonicalize = 0x00010000\n    cname_in_pa_data  = 0x00040000\n    enc_pa_rep        = 0x00010000\n    reserved1         = 0x00000001\n} -Bitfield\n\n$SECURITY_LOGON_TYPE = psenum $Module SECURITY_LOGON_TYPE UInt32 @{\n    Interactive = 2\n    Network     = 3\n    Batch       = 4\n    Service     = 5\n    Proxy       = 6\n    Unlock      = 7\n    NetworkCleartext = 8\n    NewCredentials = 9\n    RemoteInteractive = 10\n    CachedInteractive = 11\n    CachedRemoteInteractive = 12\n    CachedUnlock = 13\n}\n\n$SECURITY_IMPERSONATION_LEVEL = psenum $Module SECURITY_IMPERSONATION_LEVEL UInt32 @{\n    SecurityAnonymous = 0\n    SecurityIdentification = 1\n    SecurityImpersonation = 2\n    SecurityDelegation = 3\n}\n#endregion Enums\n\n#region Structs\n$LSA_STRING = struct $Module LSA_STRING @{\n    Length = field 0 UInt16\n    MaximumLength = field 1 UInt16\n    Buffer = field 2 IntPtr\n}\n\n$LSA_UNICODE_STRING = struct $Module LSA_UNICODE_STRING @{\n    Length = field 0 UInt16\n    MaximumLength = field 1 UInt16\n    Buffer = field 2 IntPtr\n}\n\n$LUID = struct $Module LUID @{\n    LowPart  = field 0 UInt32\n    HighPart = field 1 UInt32\n}\n\n$LUID_AND_ATTRIBUTES = struct $Module LUID_AND_ATTRIBUTES @{\n    Luid       = field 0 $LUID\n    Attributes = field 1 UInt32\n}\n\n$SecHandle = struct $Module SecHandle @{\n    dwLower = field 0 IntPtr       \n    dwUpper = field 1 IntPtr\n}\n\n$KERB_CRYPTO_KEY = struct $Module KERB_CRYPTO_KEY @{\n    KeyType = field 0 Int32\n    Length = field 1 Int32\n    Value = field 2 IntPtr\n}\n\n$KERB_EXTERNAL_NAME = struct $Module KERB_EXTERNAL_NAME @{\n    NameType = field 0 Int16\n    NameCount = field 1 UInt16\n    Names = field 2 $LSA_UNICODE_STRING\n}\n\n$KERB_EXTERNAL_TICKET = struct $Module KERB_EXTERNAL_TICKET @{\n    ServiceName = field 0 IntPtr\n    TargetName = field 1 IntPtr\n    ClientName = field 2 IntPtr\n    DomainName = field 3 $LSA_UNICODE_STRING\n    TargetDomainName = field 4 $LSA_UNICODE_STRING\n    AltTargetDomainName = field 5 $LSA_UNICODE_STRING\n    SessionKey = field 6 $KERB_CRYPTO_KEY\n    TicketFlags = field 7 UInt32\n    Flags = field 8 UInt32\n    KeyExpirationTime = field 9 Int64\n    StartTime = field 10 Int64\n    EndTime = field 11 Int64\n    RenewUntil = field 12 Int64\n    TimeSkew = field 13 Int64\n    EncodedTicketSize = field 14 Int32\n    EncodedTicket = field 15 IntPtr\n}\n\n$KERB_TICKET_CACHE_INFO = struct $Module KERB_TICKET_CACHE_INFO @{\n    ServerName = field 0 $LSA_UNICODE_STRING\n    RealmName = field 1 $LSA_UNICODE_STRING\n    StartTime = field 2 Int64\n    EndTime = field 3 Int64\n    RenewTime = field 4 Int64\n    EncryptionType = field 5 Int32\n    TicketFlags = field 6 UInt32\n}\n\n$KERB_QUERY_TKT_CACHE_REQUEST = struct $Module KERB_QUERY_TKT_CACHE_REQUEST @{\n    MessageType = field 0 $KERB_PROTOCOL_MESSAGE_TYPE\n    LogonId = field 1 $LUID\n}\n\n$KERB_QUERY_TKT_CACHE_RESPONSE = struct $Module KERB_QUERY_TKT_CACHE_RESPONSE @{\n    MessageType = field 0 $KERB_PROTOCOL_MESSAGE_TYPE\n    CountOfTickets = field 1 UInt32\n    Tickets = field 2 $KERB_TICKET_CACHE_INFO.MakeArrayType() -MarshalAs @('ByValArray', 1)\n}\n\n$KERB_RETRIEVE_TKT_REQUEST = struct $Module KERB_RETRIEVE_TKT_REQUEST @{\n    MessageType = field 0 $KERB_PROTOCOL_MESSAGE_TYPE\n    LogonId = field 1 $LUID\n    TargetName = field 2 $LSA_UNICODE_STRING\n    TicketFlags = field 3 UInt64\n    CacheOptions = field 4 $KERB_CACHE_OPTIONS\n    EncryptionType = field 5 Int64\n    CredentialsHandle = field 6 $SecHandle\n}\n\n$KERB_RETRIEVE_TKT_RESPONSE = struct $Module KERB_RETRIEVE_TKT_RESPONSE @{\n    Ticket = field 0 $KERB_EXTERNAL_TICKET\n}\n\n$LSA_LAST_INTER_LOGON_INFO = struct $Module LSA_LAST_INTER_LOGON_INFO @{\n    LastSuccessfulLogon = field 0 Int64\n    LastFailedLogon = field 1 Int64\n    FailedAttemptCountSinceLastSuccessfulLogon = field 2 UInt64\n}\n\n$SECURITY_LOGON_SESSION_DATA = struct $Module SECURITY_LOGON_SESSION_DATA @{\n    Size = field 0 UInt32\n    LogonId = field 1 $LUID\n    Username = field 2 $LSA_UNICODE_STRING\n    LogonDomain = field 3 $LSA_UNICODE_STRING\n    AuthenticationPackage = field 4 $LSA_UNICODE_STRING\n    LogonType = field 5 UInt32\n    Session = field 6 UInt32\n    PSiD = field 7 IntPtr\n    LogonTime = field 8 UInt64\n    LogonServer = field 9 $LSA_UNICODE_STRING\n    DnsDomainName = field 10 $LSA_UNICODE_STRING\n    Upn = field 11 $LSA_UNICODE_STRING\n    UserFlags = field 12 UInt64\n    LastLogonInfo = field 13 $LSA_LAST_INTER_LOGON_INFO\n    LogonScript = field 14 $LSA_UNICODE_STRING\n    ProfilePath = field 15 $LSA_UNICODE_STRING\n    HomeDirectory = field 16 $LSA_UNICODE_STRING\n    HomeDirectoryDrive = field 17 $LSA_UNICODE_STRING\n    LogoffTime = field 18 Int64\n    KickOffTime = field 19 Int64\n    PasswordLastSet = field 20 Int64\n    PasswordCanChange = field 21 Int64\n    PasswordMustChange = field 22 Int64\n}\n\n$SID_AND_ATTRIBUTES = struct $Module SID_AND_ATTRIBUTES @{\n    Sid        = field 0 IntPtr\n    Attributes = field 1 UInt32\n}\n#endregion Structs\n\n#region Function Definitions\n$FunctionDefinitions = @(\n    (func kernel32 CloseHandle ([bool]) @(\n        [IntPtr]                                  #_In_ HANDLE hObject\n    ) -EntryPoint CloseHandle -SetLastError),\n    (func advapi32 DuplicateToken ([bool]) @(\n        [IntPtr],                                 #_In_  HANDLE                       ExistingTokenHandle,\n        [UInt32],                                 #_In_  SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,\n        [IntPtr].MakeByRefType()                  #_Out_ PHANDLE                      DuplicateTokenHandle\n    ) -EntryPoint DuplicateToken -SetLastError),\n    (func advapi32 ImpersonateLoggedOnUser ([bool]) @(\n        [IntPtr]                                  #_In_ HANDLE hToken\n    ) -EntryPoint ImpersonateLoggedOnUser -SetLastError),\n    (func secur32 LsaCallAuthenticationPackage_KERB_QUERY_TKT_CACHE ([UInt32]) @(\n        [IntPtr],                                      #_In_  HANDLE    LsaHandle\n        [UInt64],                                      #_In_  ULONG     AuthenticationPackage\n        $KERB_QUERY_TKT_CACHE_REQUEST.MakeByRefType(), #_In_  PVOID     ProtocolSubmitBuffer\n        [UInt64],                                      #_In_  ULONG     SubmitBufferLength\n        [IntPtr].MakeByRefType(),#_Out_ PVOID     *ProtocolReturnBuffer\n        [UInt64].MakeByRefType(),                      #_Out_ PULONG    *ReturnBufferLength\n        [UInt32].MakeByRefType()                       #_Out_ PNTSTATUS ProtocolStatus\n    ) -EntryPoint LsaCallAuthenticationPackage),\n    (func secur32 LsaCallAuthenticationPackage_KERB_RETRIEVE_TKT ([UInt32]) @(\n        [IntPtr],                                   #_In_  HANDLE    LsaHandle\n        [UInt64],                                   #_In_  ULONG     AuthenticationPackage\n        $KERB_RETRIEVE_TKT_REQUEST.MakeByRefType(), #_In_  PVOID     ProtocolSubmitBuffer\n        [UInt64],                                   #_In_  ULONG     SubmitBufferLength\n        [IntPtr].MakeByRefType(),#_Out_ PVOID     *ProtocolReturnBuffer\n        [UInt64].MakeByRefType(),                   #_Out_ PULONG    *ReturnBufferLength\n        [UInt32].MakeByRefType()                    #_Out_ PNTSTATUS ProtocolStatus\n    ) -EntryPoint LsaCallAuthenticationPackage),\n    (func secur32 LsaConnectUntrusted ([UInt32]) @(\n        [IntPtr].MakeByRefType()                #_Out_ PHANDLE LsaHandle\n    ) -EntryPoint LsaConnectUntrusted),\n    (func secur32 LsaDeregisterLogonProcess ([UInt32]) @(\n        [IntPtr]                                #_In_ HANDLE LsaHandle\n    ) -EntryPoint LsaDeregisterLogonProcess),\n    (func secur32 LsaEnumerateLogonSessions ([UInt32]) @(\n        [UInt64].MakeByRefType(),               #_Out_ PULONG LogonSessionCount,\n        [IntPtr].MakeByRefType()                #_Out_ PLUID  *LogonSessionList\n    ) -EntryPoint LsaEnumerateLogonSessions),\n    (func secur32 LsaFreeReturnBuffer ([UInt32]) @(\n        [IntPtr].MakeByRefType()                #_In_ PVOID Buffer\n    ) -EntryPoint LsaFreeReturnBuffer),\n    (func secur32 LsaGetLogonSessionData ([UInt32]) @(\n        [IntPtr],                                    #_In_  PLUID                        LogonId,\n        [IntPtr].MakeByRefType()                     #_Out_ PSECURITY_LOGON_SESSION_DATA *ppLogonSessionData\n    ) -EntryPoint LsaGetLogonSessionData),\n    (func secur32 LsaLookupAuthenticationPackage ([UInt32]) @(\n        [IntPtr],                               #_In_  HANDLE      LsaHandle,\n        $LSA_STRING.MakeByRefType()             #_In_  PLSA_STRING PackageName,\n        [UInt64].MakeByRefType()                #_Out_ PULONG      AuthenticationPackage\n    ) -EntryPoint LsaLookupAuthenticationPackage),\n    (func advapi32 LsaNtStatusToWinError ([UInt64]) @(\n        [UInt32]                                #_In_ NTSTATUS Status\n    ) -EntryPoint LsaNtStatusToWinError),\n    (func secur32 LsaRegisterLogonProcess ([UInt32]) @(\n        $LSA_STRING.MakeByRefType()             #_In_  PLSA_STRING           LogonProcessName,\n        [IntPtr].MakeByRefType()                #_Out_ PHANDLE               LsaHandle,\n        [UInt64].MakeByRefType()                #_Out_ PLSA_OPERATIONAL_MODE SecurityMode\n    ) -EntryPoint LsaRegisterLogonProcess),\n    (func advapi32 OpenProcessToken ([bool]) @(\n        [IntPtr],                                   #_In_  HANDLE  ProcessHandle\n        [UInt32],                                   #_In_  DWORD   DesiredAccess\n        [IntPtr].MakeByRefType()                    #_Out_ PHANDLE TokenHandle\n    ) -EntryPoint OpenProcessToken -SetLastError),\n    (func advapi32 RevertToSelf ([bool]) @() -EntryPoint RevertToSelf -SetLastError)\n)\n\n$Types = $FunctionDefinitions | Add-Win32Type -Module $Module -Namespace 'Kerberos'\n$Advapi32 = $Types['advapi32']\n$Kernel32 = $Types['kernel32']\n$Secur32 = $Types['secur32']\n#endregion Function Definitions\n\n#region Win32 function abstractions\nfunction CloseHandle\n{\n    <#\n    .SYNOPSIS\n\n    Closes an open object handle.\n\n    .DESCRIPTION\n\n    The CloseHandle function closes handles to the following objects:\n    - Access token\n    - Communications device\n    - Console input\n    - Console screen buffer\n    - Event\n    - File\n    - File mapping\n    - I/O completion port\n    - Job\n    - Mailslot\n    - Memory resource notification\n    - Mutex\n    - Named pipe\n    - Pipe\n    - Process\n    - Semaphore\n    - Thread\n    - Transaction\n    - Waitable timer\n    \n    The documentation for the functions that create these objects indicates that CloseHandle should be used when you are finished with the object, and what happens to pending operations on the object after the handle is closed. In general, CloseHandle invalidates the specified object handle, decrements the object's handle count, and performs object retention checks. After the last handle to an object is closed, the object is removed from the system. \n\n    .PARAMETER Handle\n\n    A valid handle to an open object.\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: None\n    Optional Dependencies: None\n    \n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/ms724211(v=vs.85).aspx\n\n    .EXAMPLE\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $Handle    \n    )\n    \n    <#\n    (func kernel32 CloseHandle ([bool]) @(\n        [IntPtr] #_In_ HANDLE hObject\n    ) -SetLastError)\n    #>\n    \n    $SUCCESS = $Kernel32::CloseHandle($Handle); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n\n    if(-not $SUCCESS) \n    {\n        Write-Debug \"CloseHandle Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n}\n\nfunction DuplicateToken\n{\n    <#\n    .SYNOPSIS\n\n    The DuplicateToken function creates a new access token that duplicates one already in existence.\n\n    .DESCRIPTION\n\n    The DuplicateToken function creates an impersonation token, which you can use in functions such as SetThreadToken and ImpersonateLoggedOnUser. The token created by DuplicateToken cannot be used in the CreateProcessAsUser function, which requires a primary token. To create a token that you can pass to CreateProcessAsUser, use the DuplicateTokenEx function.\n\n    .PARAMETER TokenHandle\n\n    A handle to an access token opened with TOKEN_DUPLICATE access.\n\n    .NOTES\n    \n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: None\n    Optional Dependencies: None\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa446616(v=vs.85).aspx\n\n    .EXAMPLE\n\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $TokenHandle\n    )\n\n    <#\n    (func advapi32 DuplicateToken ([bool]) @(\n        [IntPtr]                                  #_In_  HANDLE                       ExistingTokenHandle,\n        [UInt32]                                  #_In_  SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,\n        [IntPtr].MakeByRefType()                  #_Out_ PHANDLE                      DuplicateTokenHandle\n    ) -SetLastError)\n    #>\n\n    $DuplicateTokenHandle = [IntPtr]::Zero\n\n    $success = $Advapi32::DuplicateToken($TokenHandle, $SECURITY_IMPERSONATION_LEVEL::SecurityImpersonation, [ref]$DuplicateTokenHandle); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n    \n    if(-not $success)\n    {\n        Write-Debug \"DuplicateToken Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n\n    Write-Output $DuplicateTokenHandle\n}\n\nfunction ImpersonateLoggedOnUser\n{\n    <#\n    .SYNOPSIS\n\n    The ImpersonateLoggedOnUser function lets the calling thread impersonate the security context of a logged-on user. The user is represented by a token handle.\n\n    .DESCRIPTION\n\n    The impersonation lasts until the thread exits or until it calls RevertToSelf.\n    \n    The calling thread does not need to have any particular privileges to call ImpersonateLoggedOnUser.\n    \n    If the call to ImpersonateLoggedOnUser fails, the client connection is not impersonated and the client request is made in the security context of the process. If the process is running as a highly privileged account, such as LocalSystem, or as a member of an administrative group, the user may be able to perform actions they would otherwise be disallowed. Therefore, it is important to always check the return value of the call, and if it fails, raise an error; do not continue execution of the client request.\n    \n    All impersonate functions, including ImpersonateLoggedOnUser allow the requested impersonation if one of the following is true:\n    - The requested impersonation level of the token is less than SecurityImpersonation, such as SecurityIdentification or SecurityAnonymous.\n    - The caller has the SeImpersonatePrivilege privilege.\n    - A process (or another process in the caller's logon session) created the token using explicit credentials through LogonUser or LsaLogonUser function.\n    - The authenticated identity is same as the caller.\n    \n    Windows XP with SP1 and earlier:  The SeImpersonatePrivilege privilege is not supported.\n\n    .PARAMETER TokenHandle\n\n    A handle to a primary or impersonation access token that represents a logged-on user. This can be a token handle returned by a call to LogonUser, CreateRestrictedToken, DuplicateToken, DuplicateTokenEx, OpenProcessToken, or OpenThreadToken functions. If hToken is a handle to a primary token, the token must have TOKEN_QUERY and TOKEN_DUPLICATE access. If hToken is a handle to an impersonation token, the token must have TOKEN_QUERY and TOKEN_IMPERSONATE access.\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: None\n    Optional Dependencies: None\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa378612(v=vs.85).aspx\n\n    .EXAMPLE\n\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $TokenHandle\n    )\n    <#\n    (func advapi32 ImpersonateLoggedOnUser ([bool]) @(\n        [IntPtr] #_In_ HANDLE hToken\n    ) -SetLastError),\n    #>\n\n    $SUCCESS = $Advapi32::ImpersonateLoggedOnUser($TokenHandle); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n    \n    if(-not $SUCCESS)\n    {\n        throw \"ImpersonateLoggedOnUser Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n}\n\nfunction LsaCallAuthenticationPackage\n{\n    <#\n    .SYNOPSIS\n\n    The LsaCallAuthenticationPackage function is used by a logon application to communicate with an authentication package.\n    \n    This function is typically used to access services provided by the authentication package.\n\n    .DESCRIPTION\n\n    Logon applications can call LsaCallAuthenticationPackage to communicate with an authentication package. There are several reasons why an application may do this:\n    \n    - To implement multiple-message authentication protocols, such as the NTLM Challenge-Response protocol.\n    - To pass state change information to the authentication package. For example, the NTLM might notify the MSV1_0 package that a previously unreachable domain controller is now reachable. The authentication package would then re-logon any users logged on to that domain controller.\n    \n    Typically, this function is used to exchange information with a custom authentication package. This function is not needed by an application that is using one of the authentication packages supplied with Windows, such as MSV1_0 or Kerberos.\n    \n    You must call LsaCallAuthenticationPackage to clean up PKINIT device credentials for LOCAL_SYSTEM and NETWORK_SERVICE. When there is no PKINIT device credential, a successful call does no operation. When there is a PKINIT device credential, a successful call cleans up the PKINIT device credential so that only the password credential remains.\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: None\n    Optional Dependencies: None\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa378261(v=vs.85).aspx\n\n    .EXAMPLE\n\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $LsaHandle,\n\n        [Parameter()]\n        [ValidateSet('MSV1_0_PACKAGE_NAME', 'MICROSOFT_KERBEROS_NAME_A', 'NEGOSSP_NAME_A', 'NTLMSP_NAME_A')]\n        [string]\n        $AuthenticationPackageName = 'MICROSOFT_KERBEROS_NAME_A',\n\n        [Parameter(Mandatory = $true)]\n        [UInt32]\n        $LogonId\n    )\n\n    <#\n    (func secur32 LsaCallAuthenticationPackage ([UInt32]) @(\n        [IntPtr],                                  #_In_  HANDLE    LsaHandle\n        [UInt64],                                  #_In_  ULONG     AuthenticationPackage\n        $KERB_RETRIEVE_TKT_REQUEST.MakeByRefType(),#_In_  PVOID     ProtocolSubmitBuffer\n        [UInt64],                                  #_In_  ULONG     SubmitBufferLength\n        [IntPtr],                                  #_Out_ PVOID     *ProtocolReturnBuffer\n        [UInt64].MakeByRefType(),                  #_Out_ PULONG    *ReturnBufferLength\n        [UInt32].MakeByRefType()                   #_Out_ PNTSTATUS ProtocolStatus\n    ))\n    #>\n\n    $AuthenticationPackage = LsaLookupAuthenticationPackage -LsaHandle $LsaHandle -PackageName $AuthenticationPackageName\n\n    switch($AuthenticationPackageName)\n    {\n        MSV1_0_PACKAGE_NAME\n        {\n            throw New-Object -TypeName System.NotImplementedException(\"MSV1_0_PACKAGE_NAME Package has not been implemented yet.\")\n        }\n        MICROSOFT_KERBEROS_NAME_A\n        {\n            # Request information about all of the cached tickets for the specified user logon session\n            <#\n            $KERB_QUERY_TKT_CACHE_REQUEST = struct $Mod Kerberos.KERB_QUERY_TKT_CACHE_REQUEST @{\n                MessageType = field 0 $KERB_PROTOCOL_MESSAGE_TYPE\n                LogonId = field 1 $LUID\n            }\n            #>\n            $ProtocolSubmitBuffer = [Activator]::CreateInstance($KERB_QUERY_TKT_CACHE_REQUEST)\n            $ProtocolSubmitBuffer.MessageType = $KERB_PROTOCOL_MESSAGE_TYPE::KerbQueryTicketCacheMessage\n            $LogonIdLuid = [Activator]::CreateInstance($LUID)\n            $LogonIdLuid.LowPart = $LogonId\n            $LogonIdLuid.HighPart = 0\n            $ProtocolSubmitBuffer.LogonId = $LogonIdLuid\n\n            $ProtocolReturnBuffer = [IntPtr]::Zero\n            $ReturnBufferLength = [UInt64]0\n            $ProtocolStatus = [UInt32]0 \n\n            $SUCCESS = $Secur32::LsaCallAuthenticationPackage_KERB_QUERY_TKT_CACHE($LsaHandle, $AuthenticationPackage, [ref]$ProtocolSubmitBuffer, $KERB_RETRIEVE_TKT_REQUEST::GetSize(), [ref]$ProtocolReturnBuffer, [ref]$ReturnBufferLength, [ref]$ProtocolStatus)\n\n            if($SUCCESS -eq 0)\n            {\n                if($ProtocolStatus -eq 0)\n                {\n                    $Response = $ProtocolReturnBuffer -as $KERB_QUERY_TKT_CACHE_RESPONSE\n\n                    for($i = 0; $i -lt $Response.CountOfTickets; $i++)\n                    {\n                        $currentTicketPtr = [IntPtr]::Add($ProtocolReturnBuffer, (8 + ($i * $KERB_TICKET_CACHE_INFO::GetSize())))\n                        $data = $currentTicketPtr -as $KERB_TICKET_CACHE_INFO\n                            \n                        $StartTime = [DateTime]::FromFileTime($data.StartTime)\n                        $EndTime = [DateTime]::FromFileTime($data.EndTime)\n                        [timespan]$TicketLength = $EndTime.Subtract($StartTime)\n\n                        $props = @{\n                            ServerName = ([System.Runtime.InteropServices.Marshal]::PtrToStringAuto($data.ServerName.Buffer, $data.ServerName.Length / 2))\n                            RealmName = ([System.Runtime.InteropServices.Marshal]::PtrToStringAuto($data.RealmName.Buffer, $data.RealmName.Length / 2))\n                            StartTime = $StartTime\n                            EndTime = $EndTime\n                            TicketLength = $TicketLength\n                            RenewTime = ([datetime]::FromFileTime($data.RenewTime))\n                            EncryptionType = ($data.EncryptionType -as $KERB_ENCRYPTION_TYPE).ToString()\n                            TicketFlags = ($data.TicketFlags -as $KERB_TICKET_FLAGS).ToString()\n                        }\n\n                        Write-Output $props\n                    }\n                }\n                else\n                {\n                    $WinErrorCode = LsaNtStatusToWinError -NtStatus $ProtocolStatus\n                    $LastError = [ComponentModel.Win32Exception]$WinErrorCode\n                    throw \"LsaCallAuthenticationPackage Error: $($LastError.Message)\"\n                }\n            }\n            else\n            {\n                $WinErrorCode = LsaNtStatusToWinError -NtStatus $SUCCESS\n                $LastError = [ComponentModel.Win32Exception]$WinErrorCode\n                throw \"LsaCallAuthenticationPackage Error: $($LastError.Message)\"\n            }          \n        }\n        NEGOSSP_NAME_A\n        {\n            throw New-Object -TypeName System.NotImplementedException(\"NEGOSSP_NAME_A Package has not been implemented yet.\")\n        }\n        NTLMSP_NAME_A\n        {\n            throw New-Object -TypeName System.NotImplementedException(\"NTLMSP_NAME_A Package has not been implemented yet.\")\n        }\n    }\n}\n\nfunction LsaConnectUntrusted\n{\n    <#\n    .SYNOPSIS\n\n    The LsaConnectUntrusted function establishes an untrusted connection to the LSA server.\n\n    .DESCRIPTION\n\n    LsaConnectUntrusted returns a handle to an untrusted connection; it does not verify any information about the caller. The handle should be closed using the LsaDeregisterLogonProcess function.\n    \n    If your application simply needs to query information from authentication packages, you can use the handle returned by this function in calls to LsaCallAuthenticationPackage and LsaLookupAuthenticationPackage.\n    \n    Applications with the SeTcbPrivilege privilege may create a trusted connection by calling LsaRegisterLogonProcess.\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: None\n    Optional Dependencies: None\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa378265(v=vs.85).aspx\n\n    .EXAMPLE\n\n    $hLsa = LsaConnectUntrusted\n    #>\n\n    param\n    (\n\n    )\n\n    <#\n    (func secur32 LsaConnectUntrusted ([UInt32]) @(\n        [IntPtr].MakeByRefType() #_Out_ PHANDLE LsaHandle\n    ))\n    #>\n    \n    $LsaHandle = [IntPtr]::Zero\n\n    $SUCCESS = $Secur32::LsaConnectUntrusted([ref]$LsaHandle)\n\n    if($SUCCESS -ne 0)\n    {\n        $WinErrorCode = LsaNtStatusToWinError -NtStatus $success\n        $LastError = [ComponentModel.Win32Exception]$WinErrorCode\n        throw \"LsaConnectUntrusted Error: $($LastError.Message)\"\n    }\n\n    Write-Output $LsaHandle\n}\n\nfunction LsaDeregisterLogonProcess\n{\n    <#\n    .SYNOPSIS\n\n    The LsaDeregisterLogonProcess function deletes the caller's logon application context and closes the connection to the LSA server.\n\n    .DESCRIPTION\n\n    If your logon application references the connection handle after calling the LsaDeregisterLogonProcess function, unexpected behavior can result.\n    \n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: None\n    Optional Dependencies: None\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa378269(v=vs.85).aspx\n\n    .EXAMPLE\n\n    $hLsa = LsaConnectUntrusted\n\n    #\n    # Do Somthing with the LSA Handle\n    #\n    \n    LsaDeregisterLogonProcess -LsaHandle $hLsa\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $LsaHandle\n    )\n\n    <#\n    (func secur32 LsaDeregisterLogonProcess ([UInt32]) @(\n        [IntPtr] #_In_ HANDLE LsaHandle\n    ))\n    #>\n\n    $SUCCESS = $Secur32::LsaDeregisterLogonProcess($LsaHandle)\n\n    if($SUCCESS -ne 0)\n    {\n        $WinErrorCode = LsaNtStatusToWinError -NtStatus $success\n        $LastError = [ComponentModel.Win32Exception]$WinErrorCode\n        throw \"LsaDeregisterLogonProcess Error: $($LastError.Message)\"\n    }\n}\n\nfunction LsaEnumerateLogonSessions\n{\n    <#\n    .SYNOPSIS\n\n    The LsaEnumerateLogonSessions function retrieves the set of existing logon session identifiers (LUIDs) and the number of sessions.\n\n    .DESCRIPTION\n\n    To retrieve information about the logon sessions returned by LsaEnumerateLogonSessions, call the LsaGetLogonSessionData function.\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: None\n    Optional Dependencies: None\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa378275(v=vs.85).aspx\n\n    .EXAMPLE\n\n    LsaEnumerateLogonSessions\n    8\n    2390553591808\n\n    .EXAMPLE\n\n    $SessionCount, $LogonSessionListPtr = LsaEnumerateLogonSessions\n    #>\n\n    <#\n    (func secur32 LsaEnumerateLogonSessions ([UInt32]) @(\n        [UInt64].MakeByRefType(), #_Out_ PULONG LogonSessionCount,\n        [IntPtr].MakeByRefType()  #_Out_ PLUID  *LogonSessionList\n    ))\n    #>\n\n    $LogonSessionCount = [UInt64]0\n    $LogonSessionList = [IntPtr]::Zero\n\n    $SUCCESS = $Secur32::LsaEnumerateLogonSessions([ref]$LogonSessionCount, [ref]$LogonSessionList)\n\n    if($SUCCESS -ne 0)\n    {\n        $WinErrorCode = LsaNtStatusToWinError -NtStatus $success\n        $LastError = [ComponentModel.Win32Exception]$WinErrorCode\n        throw \"LsaEnumerateLogonSessions Error: $($LastError.Message)\"\n    }\n\n    return $LogonSessionCount, $LogonSessionList\n}\n\nfunction LsaFreeReturnBuffer\n{\n    <#\n    .SYNOPSIS\n\n    The LsaFreeReturnBuffer function frees the memory used by a buffer previously allocated by the LSA.\n\n    .DESCRIPTION\n\n    Some of the LSA authentication functions allocate memory buffers to hold returned information, for example, LsaLogonUser and LsaCallAuthenticationPackage. Your application should call LsaFreeReturnBuffer to free these buffers when they are no longer needed.\n\n\n    .PARAMETER Buffer\n\n    Pointer to the buffer to be freed.\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: None\n    Optional Dependencies: None\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa378279(v=vs.85).aspx\n\n    .EXAMPLE\n\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $Buffer\n    )\n\n    <#\n    (func secur32 LsaFreeReturnBuffer ([UInt32]) @(\n        [IntPtr].MakeByRefType() #_In_ PVOID Buffer\n    ))\n    #>\n\n    $SUCCESS = $Secur32::LsaFreeReturnBuffer([ref]$Buffer)\n\n    if($SUCCESS -ne 0)\n    {\n        Write-Host \"Buffer: $($Buffer)\"\n        $WinErrorCode = LsaNtStatusToWinError -NtStatus $success\n        $LastError = [ComponentModel.Win32Exception]$WinErrorCode\n        throw \"LsaFreeReturnBuffer Error: $($LastError.Message)\"\n    }\n}\n    \nfunction LsaGetLogonSessionData\n{\n    <#\n    .SYNOPSIS\n\n    The LsaGetLogonSessionData function retrieves information about a specified logon session.\n\n    .DESCRIPTION\n\n    .Parameter LuidPtr\n\n    .Parameter SessionCount\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: None\n    Optional Dependencies: None\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa378290(v=vs.85).aspx\n\n    .EXAMPLE\n\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $LuidPtr,\n\n        [Parameter(Mandatory = $true)]\n        [UInt32]\n        $SessionCount\n    )\n\n    <#\n    (func secur32 LsaGetLogonSessionData ([UInt32]) @(\n        [IntPtr],                #_In_  PLUID                        LogonId,\n        [IntPtr].MakeByRefType() #_Out_ PSECURITY_LOGON_SESSION_DATA *ppLogonSessionData\n    ))\n    #>\n\n    $CurrentLuidPtr = $LuidPtr\n\n    for($i = 0; $i -lt $SessionCount; $i++)\n    {\n        $sessionDataPtr = [IntPtr]::Zero\n        $SUCCESS = $Secur32::LsaGetLogonSessionData($CurrentLuidPtr, [ref]$sessionDataPtr)\n\n        if($SUCCESS -ne 0)\n        {\n            $WinErrorCode = LsaNtStatusToWinError -NtStatus $success\n            $LastError = [ComponentModel.Win32Exception]$WinErrorCode\n            throw \"LsaGetLogonSessionData Error: $($LastError.Message)\"\n        }\n\n        try\n        {\n            $sessionData = $sessionDataPtr -as $SECURITY_LOGON_SESSION_DATA\n            \n            $props = @{\n                LogonId = $sessionData.LogonId.LowPart\n                UserName = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($sessionData.Username.Buffer, $sessionData.Username.Length / 2)\n                LogonDomain = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($sessionData.LogonDomain.Buffer, $sessionData.LognDomain.Length / 2)\n                AuthenticationPackage = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($sessionData.AuthenticationPackage.Buffer, $sessionData.AuthenticationPackage.Length / 2)\n                LogonType = $sessionData.LogonType -as $SECURITY_LOGON_TYPE\n                Session = $sessionData.Session\n                Sid = New-Object -TypeName System.Security.Principal.SecurityIdentifier($sessionData.PSiD)\n                LogonTime = [datetime]::FromFileTime($sessionData.LogonTime)\n                LogonServer = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($sessionData.LogonServer.Buffer, $sessionData.LogonServer.Length / 2)\n                DnsDomainName = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($sessionData.DnsDomainName.Buffer, $sessionData.DnsDomainName.Length / 2)\n                Upn =  [System.Runtime.InteropServices.Marshal]::PtrToStringUni($sessionData.Upn.Buffer, $sessionData.Upn.Length / 2)\n                UserFlags = $sessionData.UserFlags\n                LastSuccessfulLogon = $sessionData.LastLogonInfo.LastSuccessfulLogon\n                LastFailedLogon = $sessionData.LastLogonInfo.LastFailedLogon\n                FailedAttemptCountSinceLastSuccessfulLogon = $sessionData.LastLogonInfo.FailedAttemptCountSinceLastSuccessfulLogon\n                LogonScript = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($sessionData.LogonScript.Buffer, $sessionData.LogonScript.Length / 2)\n                ProfilePath = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($sessionData.ProfilePath.Buffer, $sessionData.ProfilePath.Length / 2)\n                HomeDirectory = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($sessionData.HomeDirectory.Buffer, $sessionData.HomeDirectory.Length / 2)\n                HomeDirectoryDrive = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($sessionData.HomeDirectoryDrive.Buffer, $sessionData.HomeDirectoryDrive.Length / 2)\n                LogoffTime = $sessionData.LogoffTime\n                KickOffTime = $sessionData.KickOffTime\n                PasswordLastSet = [datetime]::FromFileTime($sessionData.PasswordLastSet)\n                PasswordCanChange = [datetime]::FromFileTime($sessionData.PasswordCanChange)\n                PasswordMustChange = $sessionData.PasswordMustChange\n            }\n                    \n            $obj = New-Object -TypeName psobject -Property $props\n\n            Write-Output $obj\n        }\n        catch\n        {\n\n        }\n\n        #LsaFreeReturnBuffer -Buffer $sessionDataPtr\n        $CurrentLuidPtr = [IntPtr]($CurrentLuidPtr.ToInt64() + $LUID::GetSize())\n    }\n}\n\nfunction LsaLookupAuthenticationPackage\n{\n    <#\n    .SYNOPSIS\n\n    The LsaLookupAuthenticationPackage function obtains the unique identifier of an authentication package.\n\n    .DESCRIPTION\n\n    The authentication package identifier is used in calls to authentication functions such as LsaLogonUser and LsaCallAuthenticationPackage.\n\n    .PARAMETER LsaHandle\n\n    Handle obtained from a previous call to LsaRegisterLogonProcess or LsaConnectUntrusted.\n\n    .PARAMETER PackageName\n\n    Specifies the name of the authentication package. Supported packages are 'MSV1_0_PACKAGE_NAME', 'MICROSOFT_KERBEROS_NAME_A', 'NEGOSSP_NAME_A', and 'NTLMSP_NAME_A'.\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: None\n    Optional Dependencies: None\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa378297(v=vs.85).aspx\n\n    .EXAMPLE\n\n    $hLsa = LsaConnectUntrusted\n\n    LsaLookupAuthenticationPackage -LsaHandle $hLsa -PackageName MICROSOFT_KERBEROS_NAME_A\n    2\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $LsaHandle,\n\n        [Parameter(Mandatory = $true)]\n        [ValidateSet('MSV1_0_PACKAGE_NAME', 'MICROSOFT_KERBEROS_NAME_A', 'NEGOSSP_NAME_A', 'NTLMSP_NAME_A')]\n        [string]\n        $PackageName\n    )\n\n    <#\n    (func secur32 LsaLookupAuthenticationPackage ([UInt32]) @(\n        [IntPtr],                           #_In_  HANDLE      LsaHandle,\n        $LSA_UNICODE_STRING.MakeByRefType() #_In_  PLSA_STRING PackageName,\n        [UInt64].MakeByRefType()            #_Out_ PULONG      AuthenticationPackage\n    ))\n    #>\n\n    switch($PackageName)\n    {\n        MSV1_0_PACKAGE_NAME {$authPackageName = 'NTLM'; break}\n        MICROSOFT_KERBEROS_NAME_A {$authPackageName = 'Kerberos'; break}\n        NEGOSSP_NAME_A {$authPackageName = 'Negotiate'; break}\n        NTLMSP_NAME_A {$authPackageName = 'NTLM'; break}\n    }\n\n    $authPackageArray = [System.Text.Encoding]::ASCII.GetBytes($authPackageName)\n    [int]$size = $authPackageArray.Length\n    [IntPtr]$pnt = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($size) \n    [System.Runtime.InteropServices.Marshal]::Copy($authPackageArray, 0, $pnt, $authPackageArray.Length)\n    \n    $lsaString = [Activator]::CreateInstance($LSA_STRING)\n    $lsaString.Length = [UInt16]$authPackageArray.Length\n    $lsaString.MaximumLength = [UInt16]$authPackageArray.Length\n    $lsaString.Buffer = $pnt\n    \n    $AuthenticationPackage = [UInt64]0\n\n    $SUCCESS = $Secur32::LsaLookupAuthenticationPackage($LsaHandle, [ref]$lsaString, [ref]$AuthenticationPackage)\n    \n    if($SUCCESS -ne 0)\n    {\n        $WinErrorCode = LsaNtStatusToWinError -NtStatus $success\n        $LastError = [ComponentModel.Win32Exception]$WinErrorCode\n        throw \"LsaLookupAuthenticationPackage Error: $($LastError.Message)\"\n    }\n\n    [System.Runtime.InteropServices.Marshal]::FreeHGlobal($pnt)\n\n    Write-Output $AuthenticationPackage\n}\n\nfunction LsaNtStatusToWinError\n{\n    <#\n    .SYNOPSIS\n\n    The LsaNtStatusToWinError function converts an NTSTATUS code returned by an LSA function to a Windows error code.\n\n    .PARAMETER NtStatus\n\n    An NTSTATUS code returned by an LSA function call. This value will be converted to a System error code.\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: None\n    Optional Dependencies: None\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/ms721800(v=vs.85).aspx\n\n    .EXAMPLE\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [UInt32]\n        $NtStatus\n    )\n\n    <#\n    (func advapi32 LsaNtStatusToWinError ([UInt64]) @(\n        [UInt32] #_In_ NTSTATUS Status\n    ) -EntryPoint LsaNtStatusToWinError),\n    #>\n\n    $STATUS = $Advapi32::LsaNtStatusToWinError($NtStatus)\n\n    Write-Output $STATUS\n}\n\nfunction LsaRegisterLogonProcess\n{\n    <#\n    .SYNOPSIS\n\n    The LsaLookupAuthenticationPackage function obtains the unique identifier of an authentication package.\n\n    .DESCRIPTION\n\n    The authentication package identifier is used in calls to authentication functions such as LsaLogonUser and LsaCallAuthenticationPackage.\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: None\n    Optional Dependencies: None\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa378297(v=vs.85).aspx\n\n    .EXAMPLE\n\n    $hLsa = LsaRegisterLogonProcess\n\n    #>\n\n    <#\n    (func secur32 LsaRegisterLogonProcess ([UInt32]) @(\n        $LSA_STRING.MakeByRefType() #_In_  PLSA_STRING           LogonProcessName,\n        [IntPtr].MakeByRefType()    #_Out_ PHANDLE               LsaHandle,\n        [UInt64].MakeByRefType()    #_Out_ PLSA_OPERATIONAL_MODE SecurityMode\n    ))\n    #>\n\n    $lsaStringArray = [System.Text.Encoding]::ASCII.GetBytes(\"INVOKE-IR\")\n    [int]$size = $lsaStringArray.Length\n    [IntPtr]$pnt = [System.Runtime.InteropServices.Marshal]::AllocHGlobal($size) \n    [System.Runtime.InteropServices.Marshal]::Copy($lsaStringArray, 0, $pnt, $lsaStringArray.Length)\n    \n    $lsaString = [Activator]::CreateInstance($LSA_STRING)\n    $lsaString.Length = [UInt16]$lsaStringArray.Length\n    $lsaString.MaximumLength = [UInt16]$lsaStringArray.Length\n    $lsaString.Buffer = $pnt\n\n    $LsaHandle = [IntPtr]::Zero\n    $SecurityMode = [UInt64]0\n\n    $SUCCESS = $Secur32::LsaRegisterLogonProcess([ref]$lsaString, [ref]$LsaHandle, [ref]$SecurityMode)\n\n    if($SUCCESS -ne 0)\n    {\n        $WinErrorCode = LsaNtStatusToWinError -NtStatus $success\n        $LastError = [ComponentModel.Win32Exception]$WinErrorCode\n        throw \"LsaRegisterLogonProcess Error: $($LastError.Message)\"\n    }\n\n    Write-Output $LsaHandle\n}\n\nfunction OpenProcessToken\n{ \n    <#\n    .SYNOPSIS\n\n    The OpenProcessToken function opens the access token associated with a process.\n\n    .PARAMETER ProcessHandle\n\n    A handle to the process whose access token is opened. The process must have the PROCESS_QUERY_INFORMATION access permission.\n\n    .PARAMETER DesiredAccess\n\n    Specifies an access mask that specifies the requested types of access to the access token. These requested access types are compared with the discretionary access control list (DACL) of the token to determine which accesses are granted or denied.\n    For a list of access rights for access tokens, see Access Rights for Access-Token Objects.\n\n    .NOTES\n    \n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: None\n    Optional Dependencies: None\n    \n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa379295(v=vs.85).aspx\n    \n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa374905(v=vs.85).aspx\n\n    .EXAMPLE\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $ProcessHandle,\n        \n        [Parameter(Mandatory = $true)]\n        [UInt32]\n        $DesiredAccess  \n    )\n    \n    <#   \n    (func advapi32 OpenProcessToken ([bool]) @(\n        [IntPtr],                #_In_  HANDLE  ProcessHandle\n        [UInt32],                #_In_  DWORD   DesiredAccess\n        [IntPtr].MakeByRefType() #_Out_ PHANDLE TokenHandle\n    ) -SetLastError)\n    #>\n    \n    $hToken = [IntPtr]::Zero\n    $SUCCESS = $Advapi32::OpenProcessToken($ProcessHandle, $DesiredAccess, [ref]$hToken); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n\n    if(-not $SUCCESS) \n    {\n        Write-Debug \"OpenProcessToken Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n    \n    Write-Output $hToken\n}\n\nfunction RevertToSelf\n{\n    <#\n    .SYNOPSIS\n\n    The RevertToSelf function terminates the impersonation of a client application.\n\n    .DESCRIPTION\n\n    A process should call the RevertToSelf function after finishing any impersonation begun by using the DdeImpersonateClient, ImpersonateDdeClientWindow, ImpersonateLoggedOnUser, ImpersonateNamedPipeClient, ImpersonateSelf, ImpersonateAnonymousToken or SetThreadToken function.\n    \n    An RPC server that used the RpcImpersonateClient function to impersonate a client must call the RpcRevertToSelf or RpcRevertToSelfEx to end the impersonation.\n    \n    If RevertToSelf fails, your application continues to run in the context of the client, which is not appropriate. You should shut down the process if RevertToSelf fails.\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: None\n    Optional Dependencies: None\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa379317(v=vs.85).aspx\n\n    .EXAMPLE\n\n        RevertToSelf\n    #>\n\n    <#\n    (func advapi32 RevertToSelf ([bool]) @() -SetLastError)\n    #>\n\n    $SUCCESS = $Advapi32::RevertToSelf(); $LastError = [Runtime.InteropServices.Marshal]::GetLastWin32Error()\n    \n    if(-not $SUCCESS)\n    {\n        throw \"RevertToSelf Error: $(([ComponentModel.Win32Exception] $LastError).Message)\"\n    }\n}\n#endregion Win32 function abstractions\n\nStart-AceScript -Uri https://10.182.18.200 -SweepId $args[0] -ScanId ([Guid]::NewGuid()) -RoutingKey siem -Thumbprint 8D1DB3B7B85B6F9E9DE87B291DF66692A10240AE"
  },
  {
    "path": "ACE-Management/PS-ACE/Scripts/ACE_Get-LogonSession.ps1",
    "content": "﻿function Start-AceScript\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $SweepId,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $ScanId,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $RoutingKey,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Thumbprint\n    )\n\n    $HostFQDN = Get-WmiObject Win32_ComputerSystem -Property 'Name','Domain' | ForEach-Object {\"$($_.Name).$($_.Domain)\"}\n    $ResultDate = (Get-Date).ToString(\"yyyyMMddThhmmssmsmsZ\")\n\n    $dataList = New-Object -TypeName System.Collections.Generic.List['string']\n\n    foreach($o in (Get-LogonSession))\n    {\n        $o.Add('ComputerName', $HostFQDN)\n        $o.Add('ScanType', 'LogonSession')\n        $o.Add('SweepId', $SweepId)\n        $o.Add('ScanId', $ScanId)\n        $o.Add('ResultDate', $ResultDate)\n\n        $message = ConvertTo-JsonV2 -InputObject $o\n        $dataList.Add($message)\n    }\n\n    $props = @{\n        ComputerName = $HostFQDN\n        ScanType     = 'LogonSession'\n        RoutingKey   = $RoutingKey\n        ResultDate   = $ResultDate\n        ScanId       = $ScanId\n        Data         = $dataList.ToArray()\n    }\n\n    $body = (ConvertTo-JsonV2 -InputObject $props)\n    \n    Write-Host $body\n    \n    Invoke-AceWebRequest -Thumbprint $Thumbprint -Uri \"$($Uri)/ace/result/$($SweepId)\" -Body $body\n}\n\nfunction ConvertTo-JsonV2 \n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        $InputObject\n    )\n\n    Begin \n    {\n        $null = [System.Reflection.Assembly]::LoadWithPartialName(\"System.Web.Extensions\")\n        $Serializer = New-Object System.Web.Script.Serialization.JavaScriptSerializer\n    }\n\n    Process \n    {\n        try \n        {\n            $Serializer.Serialize($InputObject)\n        } \n        catch \n        {\n            Write-Error $_\n        }    \n    }\n}\n\nfunction Invoke-AceWebRequest\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Thumbprint,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Body\n    )\n\n    [Net.ServicePointManager]::ServerCertificateValidationCallback = {\n        $Thumbprint = $Thumbprint\n        $certificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]$args[1]\n    \n        if ($certificate -eq $null)\n        {\n            $Host.UI.WriteErrorLine(\"Null certificate.\")\n            return $true\n        }\n    \n        if ($certificate.Thumbprint -eq $Thumbprint)\n        {\n            return $true\n        }\n        else\n        {\n            $Host.UI.WriteErrorLine(\"Thumbprint mismatch. Certificate thumbprint $($certificate.Thumbprint)\")\n        }\n    \n        return $false\n    }\n\n    try\n    {\n        Write-Host \"URI: $($Uri)\"\n\n        # Create web request\n        $WebRequest = [Net.WebRequest]::Create($uri)\n        $WebRequest.Method = 'Post'\n        $WebRequest.ContentType = 'application/json'\n        $WebRequest.Headers.Add('X-API-Version:1.0')\n\n        $byteArray = [System.Text.Encoding]::UTF8.GetBytes($Body)\n        $Webrequest.ContentLength = $byteArray.Length\n        \n        $dataStream = $Webrequest.GetRequestStream()            \n        $dataStream.Write($byteArray, 0, $byteArray.Length)\n        $dataStream.Close()\n\n        # Get response stream\n        $ResponseStream = $Webrequest.GetResponse().GetResponseStream()\n    \n        # Create a stream reader and read the stream returning the string value.\n        $StreamReader = New-Object System.IO.StreamReader -ArgumentList $ResponseStream\n        $StreamReader.ReadToEnd()\n    }\n    catch\n    {\n        Write-Error \"Failed: $($_.exception.innerexception.message)\"\n    }\n}\n\nfunction Get-LogonSession\n{\n    <#\n\n    .SYNOPSIS\n\n    .DESCRIPTION\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: \n    Required Dependencies: PSReflect, LsaEnumerateLogonSessions (Function), LsaFreeReturnBuffer (Function), LsaGetLogonSessionData (Function) LsaNtStatusToWinError (Function), SECURITY_LOGON_SESSION_DATA (Structure), LUID (Structure), LSA_UNICODE_STRING (Structure), LSA_LAST_INTER_LOGON_INFO (Structure), SecurityEntity (Enumeration), SECURITY_LOGON_TYPE (Enumeration)\n    Optional Dependencies: None\n\n    .LINK\n\n    .EXAMPLE\n\n    Get-LogonSession\n\n    FailedAttemptCountSinceLastSuccessfulLogon : 0\n    DnsDomainName                              : HUNT.LOCAL\n    KickOffTime                                : 1/1/1601 1:00:00 AM\n    PasswordCanChange                          : 5/20/2017 9:51:20 PM\n    Upn                                        : Administrator@HUNT.LOCAL\n    UserName                                   : Administrator\n    Session                                    : 1\n    LogoffTime                                 : 1/1/1601 1:00:00 AM\n    LastFailedLogon                            : 1/1/1601 1:00:00 AM\n    LogonServer                                : DC\n    Sid                                        : S-1-5-21-3250051078-751264820-3215766868-500\n    LogonScript                                : \n    UserFlags                                  : 49444\n    ProfilePath                                : \n    PasswordMustChange                         : 6/30/2017 9:51:20 PM\n    LogonId                                    : 325349\n    LogonTime                                  : 5/20/2017 9:47:34 AM\n    PasswordLastSet                            : 5/19/2017 9:51:20 PM\n    LogonDomain                                : \n    HomeDirectory                              : \n    LogonType                                  : Interactive\n    AuthenticationPackage                      : Kerberos\n    LastSuccessfulLogon                        : 1/1/1601 1:00:00 AM\n    HomeDirectoryDrive                         : \n\n    #>\n\n    [CmdletBinding()]\n    param\n    (\n\n    )\n\n    $LogonSessions = LsaEnumerateLogonSessions\n    $Sessions = LsaGetLogonSessionData -LuidPtr $LogonSessions.SessionListPointer -SessionCount $LogonSessions.SessionCount\n\n    Write-Output $Sessions\n}\n\n#region PSReflect\n\n#Requires -Version 2\n\nfunction New-InMemoryModule\n{\n<#\n.SYNOPSIS\n\nCreates an in-memory assembly and module\n\nAuthor: Matthew Graeber (@mattifestation)\nLicense: BSD 3-Clause\nRequired Dependencies: None\nOptional Dependencies: None\n \n.DESCRIPTION\n\nWhen defining custom enums, structs, and unmanaged functions, it is\nnecessary to associate to an assembly module. This helper function\ncreates an in-memory module that can be passed to the 'enum',\n'struct', and Add-Win32Type functions.\n\n.PARAMETER ModuleName\n\nSpecifies the desired name for the in-memory assembly and module. If\nModuleName is not provided, it will default to a GUID.\n\n.EXAMPLE\n\n$Module = New-InMemoryModule -ModuleName Win32\n#>\n\n    Param\n    (\n        [Parameter(Position = 0)]\n        [ValidateNotNullOrEmpty()]\n        [String]\n        $ModuleName = [Guid]::NewGuid().ToString()\n    )\n\n    $AppDomain = [Reflection.Assembly].Assembly.GetType('System.AppDomain').GetProperty('CurrentDomain').GetValue($null, @())\n    $LoadedAssemblies = $AppDomain.GetAssemblies()\n\n    foreach ($Assembly in $LoadedAssemblies) {\n        if ($Assembly.FullName -and ($Assembly.FullName.Split(',')[0] -eq $ModuleName)) {\n            return $Assembly\n        }\n    }\n\n    $DynAssembly = New-Object Reflection.AssemblyName($ModuleName)\n    $Domain = $AppDomain\n    $AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, 'Run')\n    $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule($ModuleName, $False)\n\n    return $ModuleBuilder\n}\n\n\n# A helper function used to reduce typing while defining function\n# prototypes for Add-Win32Type.\nfunction func\n{\n    Param\n    (\n        [Parameter(Position = 0, Mandatory = $True)]\n        [String]\n        $DllName,\n\n        [Parameter(Position = 1, Mandatory = $True)]\n        [string]\n        $FunctionName,\n\n        [Parameter(Position = 2, Mandatory = $True)]\n        [Type]\n        $ReturnType,\n\n        [Parameter(Position = 3)]\n        [Type[]]\n        $ParameterTypes,\n\n        [Parameter(Position = 4)]\n        [Runtime.InteropServices.CallingConvention]\n        $NativeCallingConvention,\n\n        [Parameter(Position = 5)]\n        [Runtime.InteropServices.CharSet]\n        $Charset,\n\n        [String]\n        $EntryPoint,\n\n        [Switch]\n        $SetLastError\n    )\n\n    $Properties = @{\n        DllName = $DllName\n        FunctionName = $FunctionName\n        ReturnType = $ReturnType\n    }\n\n    if ($ParameterTypes) { $Properties['ParameterTypes'] = $ParameterTypes }\n    if ($NativeCallingConvention) { $Properties['NativeCallingConvention'] = $NativeCallingConvention }\n    if ($Charset) { $Properties['Charset'] = $Charset }\n    if ($SetLastError) { $Properties['SetLastError'] = $SetLastError }\n    if ($EntryPoint) { $Properties['EntryPoint'] = $EntryPoint }\n\n    New-Object PSObject -Property $Properties\n}\n\n\nfunction Add-Win32Type\n{\n<#\n.SYNOPSIS\n\nCreates a .NET type for an unmanaged Win32 function.\n\nAuthor: Matthew Graeber (@mattifestation)\nLicense: BSD 3-Clause\nRequired Dependencies: None\nOptional Dependencies: func\n \n.DESCRIPTION\n\nAdd-Win32Type enables you to easily interact with unmanaged (i.e.\nWin32 unmanaged) functions in PowerShell. After providing\nAdd-Win32Type with a function signature, a .NET type is created\nusing reflection (i.e. csc.exe is never called like with Add-Type).\n\nThe 'func' helper function can be used to reduce typing when defining\nmultiple function definitions.\n\n.PARAMETER DllName\n\nThe name of the DLL.\n\n.PARAMETER FunctionName\n\nThe name of the target function.\n\n.PARAMETER EntryPoint\n\nThe DLL export function name. This argument should be specified if the\nspecified function name is different than the name of the exported\nfunction.\n\n.PARAMETER ReturnType\n\nThe return type of the function.\n\n.PARAMETER ParameterTypes\n\nThe function parameters.\n\n.PARAMETER NativeCallingConvention\n\nSpecifies the native calling convention of the function. Defaults to\nstdcall.\n\n.PARAMETER Charset\n\nIf you need to explicitly call an 'A' or 'W' Win32 function, you can\nspecify the character set.\n\n.PARAMETER SetLastError\n\nIndicates whether the callee calls the SetLastError Win32 API\nfunction before returning from the attributed method.\n\n.PARAMETER Module\n\nThe in-memory module that will host the functions. Use\nNew-InMemoryModule to define an in-memory module.\n\n.PARAMETER Namespace\n\nAn optional namespace to prepend to the type. Add-Win32Type defaults\nto a namespace consisting only of the name of the DLL.\n\n.EXAMPLE\n\n$Mod = New-InMemoryModule -ModuleName Win32\n\n$FunctionDefinitions = @(\n  (func kernel32 GetProcAddress ([IntPtr]) @([IntPtr], [String]) -Charset Ansi -SetLastError),\n  (func kernel32 GetModuleHandle ([Intptr]) @([String]) -SetLastError),\n  (func ntdll RtlGetCurrentPeb ([IntPtr]) @())\n)\n\n$Types = $FunctionDefinitions | Add-Win32Type -Module $Mod -Namespace 'Win32'\n$Kernel32 = $Types['kernel32']\n$Ntdll = $Types['ntdll']\n$Ntdll::RtlGetCurrentPeb()\n$ntdllbase = $Kernel32::GetModuleHandle('ntdll')\n$Kernel32::GetProcAddress($ntdllbase, 'RtlGetCurrentPeb')\n\n.NOTES\n\nInspired by Lee Holmes' Invoke-WindowsApi http://poshcode.org/2189\n\nWhen defining multiple function prototypes, it is ideal to provide\nAdd-Win32Type with an array of function signatures. That way, they\nare all incorporated into the same in-memory module.\n#>\n\n    [OutputType([Hashtable])]\n    Param(\n        [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)]\n        [String]\n        $DllName,\n\n        [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)]\n        [String]\n        $FunctionName,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [String]\n        $EntryPoint,\n\n        [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)]\n        [Type]\n        $ReturnType,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [Type[]]\n        $ParameterTypes,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [Runtime.InteropServices.CallingConvention]\n        $NativeCallingConvention = [Runtime.InteropServices.CallingConvention]::StdCall,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [Runtime.InteropServices.CharSet]\n        $Charset = [Runtime.InteropServices.CharSet]::Auto,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [Switch]\n        $SetLastError,\n\n        [Parameter(Mandatory = $True)]\n        [ValidateScript({($_ -is [Reflection.Emit.ModuleBuilder]) -or ($_ -is [Reflection.Assembly])})]\n        $Module,\n\n        [ValidateNotNull()]\n        [String]\n        $Namespace = ''\n    )\n\n    BEGIN\n    {\n        $TypeHash = @{}\n    }\n\n    PROCESS\n    {\n        if ($Module -is [Reflection.Assembly])\n        {\n            if ($Namespace)\n            {\n                $TypeHash[$DllName] = $Module.GetType(\"$Namespace.$DllName\")\n            }\n            else\n            {\n                $TypeHash[$DllName] = $Module.GetType($DllName)\n            }\n        }\n        else\n        {\n            # Define one type for each DLL\n            if (!$TypeHash.ContainsKey($DllName))\n            {\n                if ($Namespace)\n                {\n                    $TypeHash[$DllName] = $Module.DefineType(\"$Namespace.$DllName\", 'Public,BeforeFieldInit')\n                }\n                else\n                {\n                    $TypeHash[$DllName] = $Module.DefineType($DllName, 'Public,BeforeFieldInit')\n                }\n            }\n\n            $Method = $TypeHash[$DllName].DefineMethod(\n                $FunctionName,\n                'Public,Static,PinvokeImpl',\n                $ReturnType,\n                $ParameterTypes)\n\n            # Make each ByRef parameter an Out parameter\n            $i = 1\n            foreach($Parameter in $ParameterTypes)\n            {\n                if ($Parameter.IsByRef)\n                {\n                    [void] $Method.DefineParameter($i, 'Out', $null)\n                }\n\n                $i++\n            }\n\n            $DllImport = [Runtime.InteropServices.DllImportAttribute]\n            $SetLastErrorField = $DllImport.GetField('SetLastError')\n            $CallingConventionField = $DllImport.GetField('CallingConvention')\n            $CharsetField = $DllImport.GetField('CharSet')\n            $EntryPointField = $DllImport.GetField('EntryPoint')\n            if ($SetLastError) { $SLEValue = $True } else { $SLEValue = $False }\n\n            if ($PSBoundParameters['EntryPoint']) { $ExportedFuncName = $EntryPoint } else { $ExportedFuncName = $FunctionName }\n\n            # Equivalent to C# version of [DllImport(DllName)]\n            $Constructor = [Runtime.InteropServices.DllImportAttribute].GetConstructor([String])\n            $DllImportAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($Constructor,\n                $DllName, [Reflection.PropertyInfo[]] @(), [Object[]] @(),\n                [Reflection.FieldInfo[]] @($SetLastErrorField,\n                                           $CallingConventionField,\n                                           $CharsetField,\n                                           $EntryPointField),\n                [Object[]] @($SLEValue,\n                             ([Runtime.InteropServices.CallingConvention] $NativeCallingConvention),\n                             ([Runtime.InteropServices.CharSet] $Charset),\n                             $ExportedFuncName))\n\n            $Method.SetCustomAttribute($DllImportAttribute)\n        }\n    }\n\n    END\n    {\n        if ($Module -is [Reflection.Assembly])\n        {\n            return $TypeHash\n        }\n\n        $ReturnTypes = @{}\n\n        foreach ($Key in $TypeHash.Keys)\n        {\n            $Type = $TypeHash[$Key].CreateType()\n            \n            $ReturnTypes[$Key] = $Type\n        }\n\n        return $ReturnTypes\n    }\n}\n\n\nfunction psenum\n{\n<#\n.SYNOPSIS\n\nCreates an in-memory enumeration for use in your PowerShell session.\n\nAuthor: Matthew Graeber (@mattifestation)\nLicense: BSD 3-Clause\nRequired Dependencies: None\nOptional Dependencies: None\n \n.DESCRIPTION\n\nThe 'psenum' function facilitates the creation of enums entirely in\nmemory using as close to a \"C style\" as PowerShell will allow.\n\n.PARAMETER Module\n\nThe in-memory module that will host the enum. Use\nNew-InMemoryModule to define an in-memory module.\n\n.PARAMETER FullName\n\nThe fully-qualified name of the enum.\n\n.PARAMETER Type\n\nThe type of each enum element.\n\n.PARAMETER EnumElements\n\nA hashtable of enum elements.\n\n.PARAMETER Bitfield\n\nSpecifies that the enum should be treated as a bitfield.\n\n.EXAMPLE\n\n$Mod = New-InMemoryModule -ModuleName Win32\n\n$ImageSubsystem = psenum $Mod PE.IMAGE_SUBSYSTEM UInt16 @{\n    UNKNOWN =                  0\n    NATIVE =                   1 # Image doesn't require a subsystem.\n    WINDOWS_GUI =              2 # Image runs in the Windows GUI subsystem.\n    WINDOWS_CUI =              3 # Image runs in the Windows character subsystem.\n    OS2_CUI =                  5 # Image runs in the OS/2 character subsystem.\n    POSIX_CUI =                7 # Image runs in the Posix character subsystem.\n    NATIVE_WINDOWS =           8 # Image is a native Win9x driver.\n    WINDOWS_CE_GUI =           9 # Image runs in the Windows CE subsystem.\n    EFI_APPLICATION =          10\n    EFI_BOOT_SERVICE_DRIVER =  11\n    EFI_RUNTIME_DRIVER =       12\n    EFI_ROM =                  13\n    XBOX =                     14\n    WINDOWS_BOOT_APPLICATION = 16\n}\n\n.NOTES\n\nPowerShell purists may disagree with the naming of this function but\nagain, this was developed in such a way so as to emulate a \"C style\"\ndefinition as closely as possible. Sorry, I'm not going to name it\nNew-Enum. :P\n#>\n\n    [OutputType([Type])]\n    Param\n    (\n        [Parameter(Position = 0, Mandatory = $True)]\n        [ValidateScript({($_ -is [Reflection.Emit.ModuleBuilder]) -or ($_ -is [Reflection.Assembly])})]\n        $Module,\n\n        [Parameter(Position = 1, Mandatory = $True)]\n        [ValidateNotNullOrEmpty()]\n        [String]\n        $FullName,\n\n        [Parameter(Position = 2, Mandatory = $True)]\n        [Type]\n        $Type,\n\n        [Parameter(Position = 3, Mandatory = $True)]\n        [ValidateNotNullOrEmpty()]\n        [Hashtable]\n        $EnumElements,\n\n        [Switch]\n        $Bitfield\n    )\n\n    if ($Module -is [Reflection.Assembly])\n    {\n        return ($Module.GetType($FullName))\n    }\n\n    $EnumType = $Type -as [Type]\n\n    $EnumBuilder = $Module.DefineEnum($FullName, 'Public', $EnumType)\n\n    if ($Bitfield)\n    {\n        $FlagsConstructor = [FlagsAttribute].GetConstructor(@())\n        $FlagsCustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($FlagsConstructor, @())\n        $EnumBuilder.SetCustomAttribute($FlagsCustomAttribute)\n    }\n\n    foreach ($Key in $EnumElements.Keys)\n    {\n        # Apply the specified enum type to each element\n        $null = $EnumBuilder.DefineLiteral($Key, $EnumElements[$Key] -as $EnumType)\n    }\n\n    $EnumBuilder.CreateType()\n}\n\n\n# A helper function used to reduce typing while defining struct\n# fields.\nfunction field\n{\n    Param\n    (\n        [Parameter(Position = 0, Mandatory = $True)]\n        [UInt16]\n        $Position,\n        \n        [Parameter(Position = 1, Mandatory = $True)]\n        [Type]\n        $Type,\n        \n        [Parameter(Position = 2)]\n        [UInt16]\n        $Offset,\n        \n        [Object[]]\n        $MarshalAs\n    )\n\n    @{\n        Position = $Position\n        Type = $Type -as [Type]\n        Offset = $Offset\n        MarshalAs = $MarshalAs\n    }\n}\n\n\nfunction struct\n{\n<#\n.SYNOPSIS\n\nCreates an in-memory struct for use in your PowerShell session.\n\nAuthor: Matthew Graeber (@mattifestation)\nLicense: BSD 3-Clause\nRequired Dependencies: None\nOptional Dependencies: field\n \n.DESCRIPTION\n\nThe 'struct' function facilitates the creation of structs entirely in\nmemory using as close to a \"C style\" as PowerShell will allow. Struct\nfields are specified using a hashtable where each field of the struct\nis comprosed of the order in which it should be defined, its .NET\ntype, and optionally, its offset and special marshaling attributes.\n\nOne of the features of 'struct' is that after your struct is defined,\nit will come with a built-in GetSize method as well as an explicit\nconverter so that you can easily cast an IntPtr to the struct without\nrelying upon calling SizeOf and/or PtrToStructure in the Marshal\nclass.\n\n.PARAMETER Module\n\nThe in-memory module that will host the struct. Use\nNew-InMemoryModule to define an in-memory module.\n\n.PARAMETER FullName\n\nThe fully-qualified name of the struct.\n\n.PARAMETER StructFields\n\nA hashtable of fields. Use the 'field' helper function to ease\ndefining each field.\n\n.PARAMETER PackingSize\n\nSpecifies the memory alignment of fields.\n\n.PARAMETER ExplicitLayout\n\nIndicates that an explicit offset for each field will be specified.\n\n.PARAMETER CharSet\n\nDictates which character set marshaled strings should use.\n\n.EXAMPLE\n\n$Mod = New-InMemoryModule -ModuleName Win32\n\n$ImageDosSignature = psenum $Mod PE.IMAGE_DOS_SIGNATURE UInt16 @{\n    DOS_SIGNATURE =    0x5A4D\n    OS2_SIGNATURE =    0x454E\n    OS2_SIGNATURE_LE = 0x454C\n    VXD_SIGNATURE =    0x454C\n}\n\n$ImageDosHeader = struct $Mod PE.IMAGE_DOS_HEADER @{\n    e_magic =    field 0 $ImageDosSignature\n    e_cblp =     field 1 UInt16\n    e_cp =       field 2 UInt16\n    e_crlc =     field 3 UInt16\n    e_cparhdr =  field 4 UInt16\n    e_minalloc = field 5 UInt16\n    e_maxalloc = field 6 UInt16\n    e_ss =       field 7 UInt16\n    e_sp =       field 8 UInt16\n    e_csum =     field 9 UInt16\n    e_ip =       field 10 UInt16\n    e_cs =       field 11 UInt16\n    e_lfarlc =   field 12 UInt16\n    e_ovno =     field 13 UInt16\n    e_res =      field 14 UInt16[] -MarshalAs @('ByValArray', 4)\n    e_oemid =    field 15 UInt16\n    e_oeminfo =  field 16 UInt16\n    e_res2 =     field 17 UInt16[] -MarshalAs @('ByValArray', 10)\n    e_lfanew =   field 18 Int32\n}\n\n# Example of using an explicit layout in order to create a union.\n$TestUnion = struct $Mod TestUnion @{\n    field1 = field 0 UInt32 0\n    field2 = field 1 IntPtr 0\n} -ExplicitLayout\n\n.NOTES\n\nPowerShell purists may disagree with the naming of this function but\nagain, this was developed in such a way so as to emulate a \"C style\"\ndefinition as closely as possible. Sorry, I'm not going to name it\nNew-Struct. :P\n#>\n\n    [OutputType([Type])]\n    Param\n    (\n        [Parameter(Position = 1, Mandatory = $True)]\n        [ValidateScript({($_ -is [Reflection.Emit.ModuleBuilder]) -or ($_ -is [Reflection.Assembly])})]\n        $Module,\n\n        [Parameter(Position = 2, Mandatory = $True)]\n        [ValidateNotNullOrEmpty()]\n        [String]\n        $FullName,\n\n        [Parameter(Position = 3, Mandatory = $True)]\n        [ValidateNotNullOrEmpty()]\n        [Hashtable]\n        $StructFields,\n\n        [Reflection.Emit.PackingSize]\n        $PackingSize = [Reflection.Emit.PackingSize]::Unspecified,\n\n        [Switch]\n        $ExplicitLayout,\n\n        [System.Runtime.InteropServices.CharSet]\n        $CharSet = [System.Runtime.InteropServices.CharSet]::Ansi\n    )\n\n    if ($Module -is [Reflection.Assembly])\n    {\n        return ($Module.GetType($FullName))\n    }\n\n    [Reflection.TypeAttributes] $StructAttributes = 'Class,\n        Public,\n        Sealed,\n        BeforeFieldInit'\n\n    if ($ExplicitLayout)\n    {\n        $StructAttributes = $StructAttributes -bor [Reflection.TypeAttributes]::ExplicitLayout\n    }\n    else\n    {\n        $StructAttributes = $StructAttributes -bor [Reflection.TypeAttributes]::SequentialLayout\n    }\n\n    switch($CharSet)\n    {\n        Ansi\n        {\n            $StructAttributes = $StructAttributes -bor [Reflection.TypeAttributes]::AnsiClass\n        }\n        Auto\n        {\n            $StructAttributes = $StructAttributes -bor [Reflection.TypeAttributes]::AutoClass\n        }\n        Unicode\n        {\n            $StructAttributes = $StructAttributes -bor [Reflection.TypeAttributes]::UnicodeClass\n        }\n    }\n\n    $StructBuilder = $Module.DefineType($FullName, $StructAttributes, [ValueType], $PackingSize)\n    $ConstructorInfo = [Runtime.InteropServices.MarshalAsAttribute].GetConstructors()[0]\n    $SizeConst = @([Runtime.InteropServices.MarshalAsAttribute].GetField('SizeConst'))\n\n    $Fields = New-Object Hashtable[]($StructFields.Count)\n\n    # Sort each field according to the orders specified\n    # Unfortunately, PSv2 doesn't have the luxury of the\n    # hashtable [Ordered] accelerator.\n    foreach ($Field in $StructFields.Keys)\n    {\n        $Index = $StructFields[$Field]['Position']\n        $Fields[$Index] = @{FieldName = $Field; Properties = $StructFields[$Field]}\n    }\n\n    foreach ($Field in $Fields)\n    {\n        $FieldName = $Field['FieldName']\n        $FieldProp = $Field['Properties']\n\n        $Offset = $FieldProp['Offset']\n        $Type = $FieldProp['Type']\n        $MarshalAs = $FieldProp['MarshalAs']\n\n        $NewField = $StructBuilder.DefineField($FieldName, $Type, 'Public')\n\n        if ($MarshalAs)\n        {\n            $UnmanagedType = $MarshalAs[0] -as ([Runtime.InteropServices.UnmanagedType])\n            if ($MarshalAs[1])\n            {\n                $Size = $MarshalAs[1]\n                $AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($ConstructorInfo,\n                    $UnmanagedType, $SizeConst, @($Size))\n            }\n            else\n            {\n                $AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($ConstructorInfo, [Object[]] @($UnmanagedType))\n            }\n            \n            $NewField.SetCustomAttribute($AttribBuilder)\n        }\n\n        if ($ExplicitLayout) { $NewField.SetOffset($Offset) }\n    }\n\n    # Make the struct aware of its own size.\n    # No more having to call [Runtime.InteropServices.Marshal]::SizeOf!\n    $SizeMethod = $StructBuilder.DefineMethod('GetSize',\n        'Public, Static',\n        [Int],\n        [Type[]] @())\n    $ILGenerator = $SizeMethod.GetILGenerator()\n    # Thanks for the help, Jason Shirk!\n    $ILGenerator.Emit([Reflection.Emit.OpCodes]::Ldtoken, $StructBuilder)\n    $ILGenerator.Emit([Reflection.Emit.OpCodes]::Call,\n        [Type].GetMethod('GetTypeFromHandle'))\n    $ILGenerator.Emit([Reflection.Emit.OpCodes]::Call,\n        [Runtime.InteropServices.Marshal].GetMethod('SizeOf', [Type[]] @([Type])))\n    $ILGenerator.Emit([Reflection.Emit.OpCodes]::Ret)\n\n    # Allow for explicit casting from an IntPtr\n    # No more having to call [Runtime.InteropServices.Marshal]::PtrToStructure!\n    $ImplicitConverter = $StructBuilder.DefineMethod('op_Implicit',\n        'PrivateScope, Public, Static, HideBySig, SpecialName',\n        $StructBuilder,\n        [Type[]] @([IntPtr]))\n    $ILGenerator2 = $ImplicitConverter.GetILGenerator()\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Nop)\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ldarg_0)\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ldtoken, $StructBuilder)\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Call,\n        [Type].GetMethod('GetTypeFromHandle'))\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Call,\n        [Runtime.InteropServices.Marshal].GetMethod('PtrToStructure', [Type[]] @([IntPtr], [Type])))\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Unbox_Any, $StructBuilder)\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ret)\n\n    $StructBuilder.CreateType()\n}\n\n#endregion PSReflect\n\n$Module = New-InMemoryModule -ModuleName GetLogonSession\n\n#region Enums\n$SECURITY_LOGON_TYPE = psenum $Module SECURITY_LOGON_TYPE UInt32 @{\n    Interactive             = 2\n    Network                 = 3\n    Batch                   = 4\n    Service                 = 5\n    Proxy                   = 6\n    Unlock                  = 7\n    NetworkCleartext        = 8\n    NewCredentials          = 9\n    RemoteInteractive       = 10\n    CachedInteractive       = 11\n    CachedRemoteInteractive = 12\n    CachedUnlock            = 13\n}\n\n$SecurityEntity = psenum $Module SecurityEntity UInt32 @{\n    SeCreateTokenPrivilege          = 1\n    SeAssignPrimaryTokenPrivilege   = 2\n    SeLockMemoryPrivilege           = 3\n    SeIncreaseQuotaPrivilege        = 4\n    SeUnsolicitedInputPrivilege     = 5\n    SeMachineAccountPrivilege       = 6\n    SeTcbPrivilege                  = 7\n    SeSecurityPrivilege             = 8\n    SeTakeOwnershipPrivilege        = 9\n    SeLoadDriverPrivilege           = 10\n    SeSystemProfilePrivilege        = 11\n    SeSystemtimePrivilege           = 12\n    SeProfileSingleProcessPrivilege = 13\n    SeIncreaseBasePriorityPrivilege = 14\n    SeCreatePagefilePrivilege       = 15\n    SeCreatePermanentPrivilege      = 16\n    SeBackupPrivilege               = 17\n    SeRestorePrivilege              = 18\n    SeShutdownPrivilege             = 19\n    SeDebugPrivilege                = 20\n    SeAuditPrivilege                = 21\n    SeSystemEnvironmentPrivilege    = 22\n    SeChangeNotifyPrivilege         = 23\n    SeRemoteShutdownPrivilege       = 24\n    SeUndockPrivilege               = 25\n    SeSyncAgentPrivilege            = 26\n    SeEnableDelegationPrivilege     = 27\n    SeManageVolumePrivilege         = 28\n    SeImpersonatePrivilege          = 29\n    SeCreateGlobalPrivilege         = 30\n    SeTrustedCredManAccessPrivilege = 31\n    SeRelabelPrivilege              = 32\n    SeIncreaseWorkingSetPrivilege   = 33\n    SeTimeZonePrivilege             = 34\n    SeCreateSymbolicLinkPrivilege   = 35\n}\n#endregion Enums\n\n#region Structures\n$LSA_LAST_INTER_LOGON_INFO = struct $Module LSA_LAST_INTER_LOGON_INFO @{\n    LastSuccessfulLogon                        = field 0 Int64\n    LastFailedLogon                            = field 1 Int64\n    FailedAttemptCountSinceLastSuccessfulLogon = field 2 UInt64\n}\n\n$LUID = struct $Module LUID @{\n    LowPart  = field 0 $SecurityEntity\n    HighPart = field 1 Int32\n}\n\n$LSA_UNICODE_STRING = struct $Module LSA_UNICODE_STRING @{\n    Length        = field 0 UInt16\n    MaximumLength = field 1 UInt16\n    Buffer        = field 2 IntPtr\n}\n\n$SECURITY_LOGON_SESSION_DATA = struct $Module SECURITY_LOGON_SESSION_DATA @{\n    Size                  = field 0 UInt32\n    LogonId               = field 1 $LUID\n    Username              = field 2 $LSA_UNICODE_STRING\n    LogonDomain           = field 3 $LSA_UNICODE_STRING\n    AuthenticationPackage = field 4 $LSA_UNICODE_STRING\n    LogonType             = field 5 UInt32\n    Session               = field 6 UInt32\n    PSiD                  = field 7 IntPtr\n    LogonTime             = field 8 UInt64\n    LogonServer           = field 9 $LSA_UNICODE_STRING\n    DnsDomainName         = field 10 $LSA_UNICODE_STRING\n    Upn                   = field 11 $LSA_UNICODE_STRING\n    UserFlags             = field 12 UInt64\n    LastLogonInfo         = field 13 $LSA_LAST_INTER_LOGON_INFO\n    LogonScript           = field 14 $LSA_UNICODE_STRING\n    ProfilePath           = field 15 $LSA_UNICODE_STRING\n    HomeDirectory         = field 16 $LSA_UNICODE_STRING\n    HomeDirectoryDrive    = field 17 $LSA_UNICODE_STRING\n    LogoffTime            = field 18 Int64\n    KickOffTime           = field 19 Int64\n    PasswordLastSet       = field 20 Int64\n    PasswordCanChange     = field 21 Int64\n    PasswordMustChange    = field 22 Int64\n}\n#endregion Structures\n\n#region FunctionDefinitions\n$FunctionDefinitions = @(\n    (func secur32 LsaEnumerateLogonSessions ([UInt32]) @(\n        [UInt64].MakeByRefType(), #_Out_ PULONG LogonSessionCount,\n        [IntPtr].MakeByRefType()  #_Out_ PLUID  *LogonSessionList\n    ) -EntryPoint LsaEnumerateLogonSessions),\n\n    (func secur32 LsaFreeReturnBuffer ([UInt32]) @(\n        [IntPtr] #_In_ PVOID Buffer\n    ) -EntryPoint LsaFreeReturnBuffer),\n\n    (func secur32 LsaGetLogonSessionData ([UInt32]) @(\n        [IntPtr],                #_In_  PLUID                        LogonId,\n        [IntPtr].MakeByRefType() #_Out_ PSECURITY_LOGON_SESSION_DATA *ppLogonSessionData\n    ) -EntryPoint LsaGetLogonSessionData),\n\n    (func advapi32 LsaNtStatusToWinError ([UInt64]) @(\n        [UInt32] #_In_ NTSTATUS Status\n    ) -EntryPoint LsaNtStatusToWinError)\n)\n#endregion FunctionDefinitions\n\n#region Windows API Functions\nfunction LsaEnumerateLogonSessions\n{\n    <#\n    .SYNOPSIS\n\n    The LsaEnumerateLogonSessions function retrieves the set of existing logon session identifiers (LUIDs) and the number of sessions.\n\n    .DESCRIPTION\n\n    To retrieve information about the logon sessions returned by LsaEnumerateLogonSessions, call the LsaGetLogonSessionData function.\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: PSReflect, LsaNtStatusToWinError (Function)\n    Optional Dependencies: None\n\n    (func secur32 LsaEnumerateLogonSessions ([UInt32]) @(\n        [UInt64].MakeByRefType(), #_Out_ PULONG LogonSessionCount,\n        [IntPtr].MakeByRefType()  #_Out_ PLUID  *LogonSessionList\n    ) -EntryPoint LsaEnumerateLogonSessions)\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa378275(v=vs.85).aspx\n\n    .EXAMPLE\n\n    LsaEnumerateLogonSessions\n    8\n    2390553591808\n\n    .EXAMPLE\n\n    $SessionCount, $LogonSessionListPtr = LsaEnumerateLogonSessions\n    #>\n\n    $LogonSessionCount = [UInt64]0\n    $LogonSessionList = [IntPtr]::Zero\n\n    $SUCCESS = $Secur32::LsaEnumerateLogonSessions([ref]$LogonSessionCount, [ref]$LogonSessionList)\n\n    if($SUCCESS -ne 0)\n    {\n        $WinErrorCode = LsaNtStatusToWinError -NtStatus $success\n        $LastError = [ComponentModel.Win32Exception]$WinErrorCode\n        throw \"LsaEnumerateLogonSessions Error: $($LastError.Message)\"\n    }\n\n    $obj = New-Object -TypeName psobject\n\n    $obj | Add-Member -MemberType NoteProperty -Name SessionCount -Value $LogonSessionCount\n    $obj | Add-Member -MemberType NoteProperty -Name SessionListPointer -Value $LogonSessionList\n    \n    Write-Output $obj\n}\n\nfunction LsaFreeReturnBuffer\n{\n    <#\n    .SYNOPSIS\n\n    The LsaFreeReturnBuffer function frees the memory used by a buffer previously allocated by the LSA.\n\n    .DESCRIPTION\n\n    Some of the LSA authentication functions allocate memory buffers to hold returned information, for example, LsaLogonUser and LsaCallAuthenticationPackage. Your application should call LsaFreeReturnBuffer to free these buffers when they are no longer needed.\n\n    .PARAMETER Buffer\n\n    Pointer to the buffer to be freed.\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: PSReflect, LsaNtStatusToWinError (Function)\n    Optional Dependencies: None\n\n    (func secur32 LsaFreeReturnBuffer ([UInt32]) @(\n        [IntPtr] #_In_ PVOID Buffer\n    ) -EntryPoint LsaFreeReturnBuffer)\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa378279(v=vs.85).aspx\n\n    .EXAMPLE\n\n    LsaFreeReturnBuffer -Buffer $Buffer\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $Buffer\n    )\n\n    $SUCCESS = $Secur32::LsaFreeReturnBuffer($Buffer)\n\n    if($SUCCESS -ne 0)\n    {\n        $WinErrorCode = LsaNtStatusToWinError -NtStatus $success\n        $LastError = [ComponentModel.Win32Exception]$WinErrorCode\n        throw \"LsaFreeReturnBuffer Error: $($LastError.Message)\"\n    }\n}\n\nfunction LsaGetLogonSessionData\n{\n    <#\n    .SYNOPSIS\n\n    The LsaGetLogonSessionData function retrieves information about a specified logon session.\n\n    .DESCRIPTION\n\n    .Parameter LuidPtr\n\n    .Parameter SessionCount\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: PSReflect, LsaFreeReturnBuffer (Function), LsaNtStatusToWinError (Function), SECURITY_LOGON_SESSION_DATA (Structure), LUID (Structure), LSA_UNICODE_STRING (Structure), LSA_LAST_INTER_LOGON_INFO (Structure), SecurityEntity (Enumeration), SECURITY_LOGON_TYPE (Enumeration)\n    Optional Dependencies: None\n\n    (func secur32 LsaGetLogonSessionData ([UInt32]) @(\n        [IntPtr],                #_In_  PLUID                        LogonId,\n        [IntPtr].MakeByRefType() #_Out_ PSECURITY_LOGON_SESSION_DATA *ppLogonSessionData\n    ) -EntryPoint LsaGetLogonSessionData)\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa378290(v=vs.85).aspx\n\n    .EXAMPLE\n\n    $SessionCount, $LogonSessionListPtr = LsaEnumerateLogonSessions\n    LsaGetLogonSessionData -LuidPtr $LogonSessionListPtr -SessionCount $SessionCount\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $LuidPtr,\n\n        [Parameter(Mandatory = $true)]\n        [UInt32]\n        $SessionCount\n    )\n\n    $CurrentLuidPtr = $LuidPtr\n\n    for($i = 0; $i -lt $SessionCount; $i++)\n    {\n        $sessionDataPtr = [IntPtr]::Zero\n        $SUCCESS = $Secur32::LsaGetLogonSessionData($CurrentLuidPtr, [ref]$sessionDataPtr)\n\n        if($SUCCESS -ne 0)\n        {\n            $WinErrorCode = LsaNtStatusToWinError -NtStatus $success\n            $LastError = [ComponentModel.Win32Exception]$WinErrorCode\n            throw \"LsaGetLogonSessionData Error: $($LastError.Message)\"\n        }\n\n        try\n        {\n            $sessionData = $sessionDataPtr -as $SECURITY_LOGON_SESSION_DATA\n\n            $props = @{\n                LogonId = $sessionData.LogonId.LowPart\n                UserName = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($sessionData.Username.Buffer, $sessionData.Username.Length / 2)\n                LogonDomain = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($sessionData.LogonDomain.Buffer, $sessionData.LognDomain.Length / 2)\n                AuthenticationPackage = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($sessionData.AuthenticationPackage.Buffer, $sessionData.AuthenticationPackage.Length / 2)\n                LogonType = ($sessionData.LogonType -as $SECURITY_LOGON_TYPE).ToString()\n                Session = $sessionData.Session\n                Sid = (New-Object -TypeName System.Security.Principal.SecurityIdentifier($sessionData.PSiD)).ToString()\n                LogonTime = [datetime]::FromFileTime($sessionData.LogonTime)\n                LogonServer = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($sessionData.LogonServer.Buffer, $sessionData.LogonServer.Length / 2)\n                DnsDomainName = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($sessionData.DnsDomainName.Buffer, $sessionData.DnsDomainName.Length / 2)\n                Upn =  [System.Runtime.InteropServices.Marshal]::PtrToStringUni($sessionData.Upn.Buffer, $sessionData.Upn.Length / 2)\n                UserFlags = $sessionData.UserFlags\n                LastSuccessfulLogon = $sessionData.LastLogonInfo.LastSuccessfulLogon\n                LastFailedLogon = $sessionData.LastLogonInfo.LastFailedLogon\n                FailedAttemptCountSinceLastSuccessfulLogon = $sessionData.LastLogonInfo.FailedAttemptCountSinceLastSuccessfulLogon\n                LogonScript = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($sessionData.LogonScript.Buffer, $sessionData.LogonScript.Length / 2)\n                ProfilePath = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($sessionData.ProfilePath.Buffer, $sessionData.ProfilePath.Length / 2)\n                HomeDirectory = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($sessionData.HomeDirectory.Buffer, $sessionData.HomeDirectory.Length / 2)\n                HomeDirectoryDrive = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($sessionData.HomeDirectoryDrive.Buffer, $sessionData.HomeDirectoryDrive.Length / 2)\n                LogoffTime = $sessionData.LogoffTime\n                KickOffTime = $sessionData.KickOffTime\n                PasswordLastSet = [datetime]::FromFileTime($sessionData.PasswordLastSet)\n                PasswordCanChange = [datetime]::FromFileTime($sessionData.PasswordCanChange)\n                PasswordMustChange = $sessionData.PasswordMustChange\n            }\n             \n            Write-Output $props       \n            #$obj = New-Object -TypeName psobject -Property $props\n\n            #Write-Output $obj\n        }\n        catch\n        {\n\n        }\n\n        LsaFreeReturnBuffer -Buffer $sessionDataPtr\n        $CurrentLuidPtr = [IntPtr]($CurrentLuidPtr.ToInt64() + $LUID::GetSize())\n    }\n}\n\nfunction LsaNtStatusToWinError\n{\n    <#\n    .SYNOPSIS\n\n    The LsaNtStatusToWinError function converts an NTSTATUS code returned by an LSA function to a Windows error code.\n\n    .PARAMETER NtStatus\n\n    An NTSTATUS code returned by an LSA function call. This value will be converted to a System error code.\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: PSReflect\n    Optional Dependencies: None\n\n    (func advapi32 LsaNtStatusToWinError ([UInt64]) @(\n        [UInt32] #_In_ NTSTATUS Status\n    ) -EntryPoint LsaNtStatusToWinError)\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/ms721800(v=vs.85).aspx\n\n    .EXAMPLE\n    #>\n\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [UInt32]\n        $NtStatus\n    )\n\n    $STATUS = $Advapi32::LsaNtStatusToWinError($NtStatus)\n\n    Write-Output $STATUS\n}\n#endregion Windows API Functions\n\n$Types = $FunctionDefinitions | Add-Win32Type -Module $Module -Namespace 'GetLogonSession'\n$Advapi32 = $Types['advapi32']\n$Secur32 = $Types['secur32']\n\nStart-AceScript -Uri https://10.182.18.200 -SweepId $args[0] -ScanId ([Guid]::NewGuid()) -RoutingKey siem -Thumbprint 8D1DB3B7B85B6F9E9DE87B291DF66692A10240AE"
  },
  {
    "path": "ACE-Management/PS-ACE/Scripts/ACE_Get-MasterBootRecord.ps1",
    "content": "﻿function Start-AceScript\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $SweepId,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $ScanId,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $RoutingKey,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Thumbprint\n    )\n\n    $HostFQDN = Get-WmiObject Win32_ComputerSystem -Property 'Name','Domain' | ForEach-Object {\"$($_.Name).$($_.Domain)\"}\n    $ResultDate = (Get-Date).ToString(\"yyyyMMddThhmmssmsmsZ\")\n\n    $dataList = New-Object -TypeName System.Collections.Generic.List['string']\n\n    foreach($o in (Get-MasterBootRecord  -ReturnHashtables))\n    {\n        $o.Add('ComputerName', $HostFQDN)\n        $o.Add('ScanType', 'MasterBootRecord')\n        $o.Add('SweepId', $SweepId)\n        $o.Add('ScanId', $ScanId)\n        $o.Add('ResultDate', $ResultDate)\n\n        $message = ConvertTo-JsonV2 -InputObject $o\n        $dataList.Add($message)\n    }\n\n    $props = @{\n        ComputerName = $HostFQDN\n        ScanType     = 'MasterBootRecord'\n        RoutingKey   = $RoutingKey\n        ResultDate   = $ResultDate\n        ScanId       = $ScanId\n        Data         = $dataList.ToArray()\n    }\n\n    $body = (ConvertTo-JsonV2 -InputObject $props)\n\n    Write-Host $body\n\n    Invoke-AceWebRequest -Thumbprint $Thumbprint -Uri \"$($Uri)/ace/result/$($SweepId)\" -Body $body\n}\n\nfunction ConvertTo-JsonV2 \n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        $InputObject\n    )\n\n    Begin \n    {\n        $null = [System.Reflection.Assembly]::LoadWithPartialName(\"System.Web.Extensions\")\n        $Serializer = New-Object System.Web.Script.Serialization.JavaScriptSerializer\n    }\n\n    Process \n    {\n        try \n        {\n            $Serializer.Serialize($InputObject)\n        } \n        catch \n        {\n            Write-Error $_\n        }    \n    }\n}\n\nfunction Invoke-AceWebRequest\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Thumbprint,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Body\n    )\n\n    [Net.ServicePointManager]::ServerCertificateValidationCallback = {\n        $Thumbprint = $Thumbprint\n        $certificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]$args[1]\n    \n        if ($certificate -eq $null)\n        {\n            $Host.UI.WriteErrorLine(\"Null certificate.\")\n            return $true\n        }\n    \n        if ($certificate.Thumbprint -eq $Thumbprint)\n        {\n            return $true\n        }\n        else\n        {\n            $Host.UI.WriteErrorLine(\"Thumbprint mismatch. Certificate thumbprint $($certificate.Thumbprint)\")\n        }\n    \n        return $false\n    }\n\n    try\n    {\n        Write-Host \"URI: $($Uri)\"\n\n        # Create web request\n        $WebRequest = [Net.WebRequest]::Create($uri)\n        $WebRequest.Method = 'Post'\n        $WebRequest.ContentType = 'application/json'\n        $WebRequest.Headers.Add('X-API-Version:1.0')\n\n        $byteArray = [System.Text.Encoding]::UTF8.GetBytes($Body)\n        $Webrequest.ContentLength = $byteArray.Length\n        \n        $dataStream = $Webrequest.GetRequestStream()            \n        $dataStream.Write($byteArray, 0, $byteArray.Length)\n        $dataStream.Close()\n\n        # Get response stream\n        $ResponseStream = $Webrequest.GetResponse().GetResponseStream()\n    \n        # Create a stream reader and read the stream returning the string value.\n        $StreamReader = New-Object System.IO.StreamReader -ArgumentList $ResponseStream\n        $StreamReader.ReadToEnd()\n    }\n    catch\n    {\n        Write-Error \"Failed: $($_.exception.innerexception.message)\"\n    }\n}\n\nfunction Get-MasterBootRecord {\n<#\n    .SYNOPSIS\n\n        Returns detailed information about the master boot record\n\n        Author: Jared Atkinson\n        License: BSD 3-Clause\n        Required Dependencies: None\n        Optional Dependencies: None\n\n#>\n    [CmdletBinding()]\n    Param\n    (\n        [Parameter()]\n        [String[]]\n        $Path,\n\n        [switch]\n        $ReturnHashtables\n    )\n    \n    begin\n    {\n        function Get-FileHandle\n        {\n            [CmdletBinding()]\n            param\n            (\n                [Parameter(Mandatory = $true)]\n                [string]\n                $Path\n            )\n            \n            #region Constants\n        \n            $GENERIC_READWRITE = 0x80000000\n            $FILE_SHARE_READWRITE = 0x02 -bor 0x01\n            $OPEN_EXISTING = 0x03\n        \n            #endregion\n\n            #region Reflection\n            $DynAssembly = New-Object System.Reflection.AssemblyName('Win32')\n            $AssemblyBuilder = [AppDomain]::CurrentDomain.DefineDynamicAssembly($DynAssembly, [Reflection.Emit.AssemblyBuilderAccess]::Run)\n            $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('Win32', $False)\n\n            $TypeBuilder = $ModuleBuilder.DefineType('Win32.Kernel32', 'Public, Class')\n            $DllImportConstructor = [Runtime.InteropServices.DllImportAttribute].GetConstructor(@([String]))\n            $SetLastError = [Runtime.InteropServices.DllImportAttribute].GetField('SetLastError')\n            $SetLastErrorCustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($DllImportConstructor,\n                @('kernel32.dll'),\n                [Reflection.FieldInfo[]]@($SetLastError),\n                @($True))\n\n            # Define [Win32.Kernel32]::CreateFile\n            $PInvokeMethod = $TypeBuilder.DefinePInvokeMethod('CreateFile',\n                'kernel32.dll',\n                ([Reflection.MethodAttributes]::Public -bor [Reflection.MethodAttributes]::Static),\n                [Reflection.CallingConventions]::Standard,\n                [Microsoft.Win32.SafeHandles.SafeFileHandle],\n                [Type[]]@([String], [Int32], [UInt32], [IntPtr], [UInt32], [UInt32], [IntPtr]),\n                [Runtime.InteropServices.CallingConvention]::Winapi,\n                [Runtime.InteropServices.CharSet]::Ansi)\n            $PInvokeMethod.SetCustomAttribute($SetLastErrorCustomAttribute)\n\n            $Kernel32 = $TypeBuilder.CreateType()\n            #endregion\n\n            # Get handle to $FileToServe\n            $DriveHandle = $Kernel32::CreateFile($Path, $GENERIC_READWRITE, $FILE_SHARE_READWRITE, 0, $OPEN_EXISTING, 0, 0)\n\n            # Check that handle is valid\n            if ($DriveHandle.IsInvalid) {\n                Write-Error \"Invalid handle to $($Path) returned from CreateFile\" -ErrorAction Stop\n            }\n            else {\n                $DriveHandle\n            }\n        }\n               \n        function Read-MbrBytes\n        {\n            [CmdletBinding()]\n            param\n            (\n                [Parameter(Mandatory = $true)]\n                [Microsoft.Win32.SafeHandles.SafeFileHandle]\n                $Handle\n            )\n\n            try\n            {\n                # Create a FileStream to read from the handle\n                $streamToRead = New-Object -TypeName System.IO.FileStream($Handle, [System.IO.FileAccess]::Read)\n            \n                # Set our position in the stream to $Offset\n                $streamToRead.Position = 0x0\n        \n                # Create a buffer $Length bytes long\n                $buffer = New-Object -TypeName Byte[](0x200)\n\n                # Read $Length bytes\n                $return = $streamToRead.Read($buffer, 0x0, 0x200)\n            \n                # Check return value\n                if($return -ne 0x200)\n                {\n                    $return\n                }\n\n                $buffer\n            }\n            catch\n            {\n                Write-Error \"Unable to read bytes from Drive\" -ErrorAction Stop\n            }\n            finally\n            {\n                $streamToRead.Dispose()\n            }\n        }\n        \n        function Get-MD5Hash\n        {\n            param\n            (\n                [Parameter(Mandatory = $true)]\n                [byte[]]\n                $Bytes\n            )\n            \n            begin\n            {\n                $sha1 = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider\n                $hashbytes = $sha1.ComputeHash($Bytes)\n                $sb = New-Object -TypeName System.Text.StringBuilder\n            }\n\n            process\n            {\n                foreach($b in $hashbytes)\n                {\n                    $null = $sb.Append(\"{0:x}\" -f $b)\n                }\n\n                $sb.ToString()\n            }\n\n            end\n            {\n                if($sha1.Dispose) {\n                    $sha1.Dispose()\n                }\n            }\n        }\n\n        function Get-Partition\n        {\n            param\n            (\n                [Parameter(Mandatory = $true)]\n                [byte[]]\n                $Bytes,\n\n                [Parameter(Mandatory = $true)]\n                [int]\n                $Offset,\n\n                [switch]\n                $ReturnHashtables\n            )\n\n            # Status (0x00 - Non-Bootable & 0x80 - Bootable)\n            if($Bytes[0x00 + $Offset] -eq 0x80)\n            {\n                $Bootable = $true\n            }\n            else\n            {\n                $Bootable = $false\n            }\n\n            $props = @{\n                Bootable = $Bootable\n                PartitionType = $Bytes[0x04 + $Offset]\n                RelativeStartSector = [System.BitConverter]::ToUInt32($Bytes, 0x08 + $Offset)\n                TotalSectors = [System.BitConverter]::ToUInt32($Bytes, 0x0C + $Offset)\n            }\n\n            if($ReturnHashtables) {\n                $props\n            } else {\n                New-Object -TypeName psobject -Property $props\n            }\n        }\n    }\n\n    process\n    {\n        if(-not($PSBoundParameters.ContainsKey('Path')))\n        {\n            $Disks = Get-WmiObject -Query \"SELECT * FROM Win32_DiskDrive\"\n        }\n        else\n        {\n\n        }\n\n        $OS = (Get-WmiObject win32_Operatingsystem).Caption\n\n        foreach($disk in $Disks)\n        {\n            $hDrive = Get-FileHandle -Path $disk.DeviceId\n\n            if($hDrive) {\n                $bytes = Read-MbrBytes -Handle $hDrive\n\n                $CodeSection = $bytes[0x3E..0x1B7]\n\n                $listPartitions = New-Object -TypeName System.Collections.Generic.List[HashTable]\n\n                for($i = 0; $i -lt 4; $i++)\n                {\n                    if($ReturnHashtables) {\n                        $partition = Get-Partition -Bytes $bytes -Offset (0x1BE + (0x10 * $i)) -ReturnHashtables\n                    } else {\n                        $partition = Get-Partition -Bytes $bytes -Offset (0x1BE + (0x10 * $i))\n                    }\n\n                    if($partition.TotalSectors -ne 0)\n                    {\n                        $listPartitions.Add($partition)\n                    }\n                }\n\n                $Props = @{\n                    OperatingSystem = $OS\n                    DeviceId = $disk.DeviceId\n                    Model = $disk.Model\n                    Signature = Get-MD5Hash -Bytes $CodeSection\n                    CodeSection = $CodeSection\n                    DiskSignature = [System.BitConverter]::ToString($bytes[0x1B8..0x1BB]).Replace(\"-\", \"\")\n                    PartitionTable = $listPartitions.ToArray()\n                }\n\n                if($ReturnHashtables) {\n                    $Props\n                } else {\n                    New-Object -TypeName psobject -Property $Props\n                }\n            }\n        }\n    }\n}\n\nStart-AceScript -Uri https://10.182.18.200 -SweepId $args[0] -ScanId ([Guid]::NewGuid()) -RoutingKey siem -Thumbprint 8D1DB3B7B85B6F9E9DE87B291DF66692A10240AE"
  },
  {
    "path": "ACE-Management/PS-ACE/Scripts/ACE_Get-NetworkConnection.ps1",
    "content": "﻿function Start-AceScript\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $SweepId,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $ScanId,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $RoutingKey,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Thumbprint\n    )\n\n    $HostFQDN = Get-WmiObject Win32_ComputerSystem -Property 'Name','Domain' | ForEach-Object {\"$($_.Name).$($_.Domain)\"}\n    $ResultDate = (Get-Date).ToString(\"yyyyMMddThhmmssmsmsZ\")\n\n    $dataList = New-Object -TypeName System.Collections.Generic.List['string']\n\n    foreach($o in (Get-NetworkConnection -ReturnHashtables))\n    {\n        $o.Add('ComputerName', $HostFQDN)\n        $o.Add('ScanType', 'NetworkConnection')\n        $o.Add('SweepId', $SweepId)\n        $o.Add('ScanId', $ScanId)\n        $o.Add('ResultDate', $ResultDate)\n\n        $message = ConvertTo-JsonV2 -InputObject $o\n        $dataList.Add($message)\n    }\n\n    $props = @{\n        ComputerName = $HostFQDN\n        ScanType     = 'NetworkConnection'\n        RoutingKey   = $RoutingKey\n        ResultDate   = $ResultDate\n        ScanId       = $ScanId\n        Data         = $dataList.ToArray()\n    }\n\n    $body = (ConvertTo-JsonV2 -InputObject $props)\n\n    Write-Output $body\n\n    Invoke-AceWebRequest -Thumbprint $Thumbprint -Uri \"$($Uri)/ace/result/$($SweepId)\" -Body $body\n}\n\nfunction ConvertTo-JsonV2 \n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        $InputObject\n    )\n\n    Begin \n    {\n        $null = [System.Reflection.Assembly]::LoadWithPartialName(\"System.Web.Extensions\")\n        $Serializer = New-Object System.Web.Script.Serialization.JavaScriptSerializer\n    }\n\n    Process \n    {\n        try \n        {\n            $Serializer.Serialize($InputObject)\n        } \n        catch \n        {\n            Write-Error $_\n        }    \n    }\n}\n\nfunction Invoke-AceWebRequest\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Thumbprint,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Body\n    )\n\n    [Net.ServicePointManager]::ServerCertificateValidationCallback = {\n        $Thumbprint = $Thumbprint\n        $certificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]$args[1]\n    \n        if ($certificate -eq $null)\n        {\n            $Host.UI.WriteErrorLine(\"Null certificate.\")\n            return $true\n        }\n    \n        if ($certificate.Thumbprint -eq $Thumbprint)\n        {\n            return $true\n        }\n        else\n        {\n            $Host.UI.WriteErrorLine(\"Thumbprint mismatch. Certificate thumbprint $($certificate.Thumbprint)\")\n        }\n    \n        return $false\n    }\n\n    try\n    {\n        Write-Host \"URI: $($Uri)\"\n\n        # Create web request\n        $WebRequest = [Net.WebRequest]::Create($uri)\n        $WebRequest.Method = 'Post'\n        $WebRequest.ContentType = 'application/json'\n        $WebRequest.Headers.Add('X-API-Version:1.0')\n\n        $byteArray = [System.Text.Encoding]::UTF8.GetBytes($Body)\n        $Webrequest.ContentLength = $byteArray.Length\n        \n        $dataStream = $Webrequest.GetRequestStream()            \n        $dataStream.Write($byteArray, 0, $byteArray.Length)\n        $dataStream.Close()\n\n        # Get response stream\n        $ResponseStream = $Webrequest.GetResponse().GetResponseStream()\n    \n        # Create a stream reader and read the stream returning the string value.\n        $StreamReader = New-Object System.IO.StreamReader -ArgumentList $ResponseStream\n        $StreamReader.ReadToEnd()\n    }\n    catch\n    {\n        Write-Error \"Failed: $($_.exception.innerexception.message)\"\n    }\n}\n\nfunction Get-NetworkConnection {\n    <#\n    .SYNOPSIS\n\n    Returns current TCP and UDP connections.\n\n    .NOTES\n\n    Author: Lee Christensen (@tifkin_)\n    License: BSD 3-Clause\n    Required Dependencies: None\n    Optional Dependencies: None\n    #>\n    [CmdletBinding()]\n    param \n    (\n        [switch]\n        $ResolveHostnames,\n\n        [switch]\n        $ReturnHashtables\n    )\n\n    $Tcp4Connections = Get-Tcp4Connections @PSBoundParameters\n    $Tcp6Connections = Get-Tcp6Connections @PSBoundParameters\n    $Udp4Connections = Get-Udp4Connections @PSBoundParameters\n    $Udp6Connections = Get-Udp6Connections @PSBoundParameters\n\n    $Tcp4Connections\n    $Tcp6Connections\n    $Udp4Connections\n    $Udp6Connections\n}\n\n#region PSReflect\nfunction New-InMemoryModule\n{\n<#\n.SYNOPSIS\n\nCreates an in-memory assembly and module\n\nAuthor: Matthew Graeber (@mattifestation)\nLicense: BSD 3-Clause\nRequired Dependencies: None\nOptional Dependencies: None\n \n.DESCRIPTION\n\nWhen defining custom enums, structs, and unmanaged functions, it is\nnecessary to associate to an assembly module. This helper function\ncreates an in-memory module that can be passed to the 'enum',\n'struct', and Add-Win32Type functions.\n\n.PARAMETER ModuleName\n\nSpecifies the desired name for the in-memory assembly and module. If\nModuleName is not provided, it will default to a GUID.\n\n.EXAMPLE\n\n$Module = New-InMemoryModule -ModuleName Win32\n#>\n\n    Param\n    (\n        [Parameter(Position = 0)]\n        [ValidateNotNullOrEmpty()]\n        [String]\n        $ModuleName = [Guid]::NewGuid().ToString()\n    )\n\n    $LoadedAssemblies = [AppDomain]::CurrentDomain.GetAssemblies()\n\n    foreach ($Assembly in $LoadedAssemblies) {\n        if ($Assembly.FullName -and ($Assembly.FullName.Split(',')[0] -eq $ModuleName)) {\n            return $Assembly\n        }\n    }\n\n    $DynAssembly = New-Object Reflection.AssemblyName($ModuleName)\n    $Domain = [AppDomain]::CurrentDomain\n    $AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, 'Run')\n    $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule($ModuleName, $False)\n\n    return $ModuleBuilder\n}\n\n\n# A helper function used to reduce typing while defining function\n# prototypes for Add-Win32Type.\nfunction func\n{\n    Param\n    (\n        [Parameter(Position = 0, Mandatory = $True)]\n        [String]\n        $DllName,\n\n        [Parameter(Position = 1, Mandatory = $True)]\n        [string]\n        $FunctionName,\n\n        [Parameter(Position = 2, Mandatory = $True)]\n        [Type]\n        $ReturnType,\n\n        [Parameter(Position = 3)]\n        [Type[]]\n        $ParameterTypes,\n\n        [Parameter(Position = 4)]\n        [Runtime.InteropServices.CallingConvention]\n        $NativeCallingConvention,\n\n        [Parameter(Position = 5)]\n        [Runtime.InteropServices.CharSet]\n        $Charset,\n\n        [String]\n        $EntryPoint,\n\n        [Switch]\n        $SetLastError\n    )\n\n    $Properties = @{\n        DllName = $DllName\n        FunctionName = $FunctionName\n        ReturnType = $ReturnType\n    }\n\n    if ($ParameterTypes) { $Properties['ParameterTypes'] = $ParameterTypes }\n    if ($NativeCallingConvention) { $Properties['NativeCallingConvention'] = $NativeCallingConvention }\n    if ($Charset) { $Properties['Charset'] = $Charset }\n    if ($SetLastError) { $Properties['SetLastError'] = $SetLastError }\n    if ($EntryPoint) { $Properties['EntryPoint'] = $EntryPoint }\n\n    New-Object PSObject -Property $Properties\n}\n\n\nfunction Add-Win32Type\n{\n<#\n.SYNOPSIS\n\nCreates a .NET type for an unmanaged Win32 function.\n\nAuthor: Matthew Graeber (@mattifestation)\nLicense: BSD 3-Clause\nRequired Dependencies: None\nOptional Dependencies: func\n \n.DESCRIPTION\n\nAdd-Win32Type enables you to easily interact with unmanaged (i.e.\nWin32 unmanaged) functions in PowerShell. After providing\nAdd-Win32Type with a function signature, a .NET type is created\nusing reflection (i.e. csc.exe is never called like with Add-Type).\n\nThe 'func' helper function can be used to reduce typing when defining\nmultiple function definitions.\n\n.PARAMETER DllName\n\nThe name of the DLL.\n\n.PARAMETER FunctionName\n\nThe name of the target function.\n\n.PARAMETER EntryPoint\n\nThe DLL export function name. This argument should be specified if the\nspecified function name is different than the name of the exported\nfunction.\n\n.PARAMETER ReturnType\n\nThe return type of the function.\n\n.PARAMETER ParameterTypes\n\nThe function parameters.\n\n.PARAMETER NativeCallingConvention\n\nSpecifies the native calling convention of the function. Defaults to\nstdcall.\n\n.PARAMETER Charset\n\nIf you need to explicitly call an 'A' or 'W' Win32 function, you can\nspecify the character set.\n\n.PARAMETER SetLastError\n\nIndicates whether the callee calls the SetLastError Win32 API\nfunction before returning from the attributed method.\n\n.PARAMETER Module\n\nThe in-memory module that will host the functions. Use\nNew-InMemoryModule to define an in-memory module.\n\n.PARAMETER Namespace\n\nAn optional namespace to prepend to the type. Add-Win32Type defaults\nto a namespace consisting only of the name of the DLL.\n\n.EXAMPLE\n\n$Mod = New-InMemoryModule -ModuleName Win32\n\n$FunctionDefinitions = @(\n    (func kernel32 GetProcAddress ([IntPtr]) @([IntPtr], [String]) -Charset Ansi -SetLastError),\n    (func kernel32 GetModuleHandle ([Intptr]) @([String]) -SetLastError),\n    (func ntdll RtlGetCurrentPeb ([IntPtr]) @())\n)\n\n$Types = $FunctionDefinitions | Add-Win32Type -Module $Mod -Namespace 'Win32'\n$Kernel32 = $Types['kernel32']\n$Ntdll = $Types['ntdll']\n$Ntdll::RtlGetCurrentPeb()\n$ntdllbase = $Kernel32::GetModuleHandle('ntdll')\n$Kernel32::GetProcAddress($ntdllbase, 'RtlGetCurrentPeb')\n\n.NOTES\n\nInspired by Lee Holmes' Invoke-WindowsApi http://poshcode.org/2189\n\nWhen defining multiple function prototypes, it is ideal to provide\nAdd-Win32Type with an array of function signatures. That way, they\nare all incorporated into the same in-memory module.\n#>\n\n    [OutputType([Hashtable])]\n    Param(\n        [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)]\n        [String]\n        $DllName,\n\n        [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)]\n        [String]\n        $FunctionName,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [String]\n        $EntryPoint,\n\n        [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)]\n        [Type]\n        $ReturnType,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [Type[]]\n        $ParameterTypes,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [Runtime.InteropServices.CallingConvention]\n        $NativeCallingConvention = [Runtime.InteropServices.CallingConvention]::StdCall,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [Runtime.InteropServices.CharSet]\n        $Charset = [Runtime.InteropServices.CharSet]::Auto,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [Switch]\n        $SetLastError,\n\n        [Parameter(Mandatory = $True)]\n        [ValidateScript({($_ -is [Reflection.Emit.ModuleBuilder]) -or ($_ -is [Reflection.Assembly])})]\n        $Module,\n\n        [ValidateNotNull()]\n        [String]\n        $Namespace = ''\n    )\n\n    BEGIN\n    {\n        $TypeHash = @{}\n    }\n\n    PROCESS\n    {\n        if ($Module -is [Reflection.Assembly])\n        {\n            if ($Namespace)\n            {\n                $TypeHash[$DllName] = $Module.GetType(\"$Namespace.$DllName\")\n            }\n            else\n            {\n                $TypeHash[$DllName] = $Module.GetType($DllName)\n            }\n        }\n        else\n        {\n            # Define one type for each DLL\n            if (!$TypeHash.ContainsKey($DllName))\n            {\n                if ($Namespace)\n                {\n                    $TypeHash[$DllName] = $Module.DefineType(\"$Namespace.$DllName\", 'Public,BeforeFieldInit')\n                }\n                else\n                {\n                    $TypeHash[$DllName] = $Module.DefineType($DllName, 'Public,BeforeFieldInit')\n                }\n            }\n\n            $Method = $TypeHash[$DllName].DefineMethod(\n                $FunctionName,\n                'Public,Static,PinvokeImpl',\n                $ReturnType,\n                $ParameterTypes)\n\n            # Make each ByRef parameter an Out parameter\n            $i = 1\n            foreach($Parameter in $ParameterTypes)\n            {\n                if ($Parameter.IsByRef)\n                {\n                    [void] $Method.DefineParameter($i, 'Out', $null)\n                }\n\n                $i++\n            }\n\n            $DllImport = [Runtime.InteropServices.DllImportAttribute]\n            $SetLastErrorField = $DllImport.GetField('SetLastError')\n            $CallingConventionField = $DllImport.GetField('CallingConvention')\n            $CharsetField = $DllImport.GetField('CharSet')\n            $EntryPointField = $DllImport.GetField('EntryPoint')\n            if ($SetLastError) { $SLEValue = $True } else { $SLEValue = $False }\n\n            if ($PSBoundParameters['EntryPoint']) { $ExportedFuncName = $EntryPoint } else { $ExportedFuncName = $FunctionName }\n\n            # Equivalent to C# version of [DllImport(DllName)]\n            $Constructor = [Runtime.InteropServices.DllImportAttribute].GetConstructor([String])\n            $DllImportAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($Constructor,\n                $DllName, [Reflection.PropertyInfo[]] @(), [Object[]] @(),\n                [Reflection.FieldInfo[]] @($SetLastErrorField,\n                                            $CallingConventionField,\n                                            $CharsetField,\n                                            $EntryPointField),\n                [Object[]] @($SLEValue,\n                                ([Runtime.InteropServices.CallingConvention] $NativeCallingConvention),\n                                ([Runtime.InteropServices.CharSet] $Charset),\n                                $ExportedFuncName))\n\n            $Method.SetCustomAttribute($DllImportAttribute)\n        }\n    }\n\n    END\n    {\n        if ($Module -is [Reflection.Assembly])\n        {\n            return $TypeHash\n        }\n\n        $ReturnTypes = @{}\n\n        foreach ($Key in $TypeHash.Keys)\n        {\n            $Type = $TypeHash[$Key].CreateType()\n            \n            $ReturnTypes[$Key] = $Type\n        }\n\n        return $ReturnTypes\n    }\n}\n\n\nfunction psenum\n{\n<#\n.SYNOPSIS\n\nCreates an in-memory enumeration for use in your PowerShell session.\n\nAuthor: Matthew Graeber (@mattifestation)\nLicense: BSD 3-Clause\nRequired Dependencies: None\nOptional Dependencies: None\n \n.DESCRIPTION\n\nThe 'psenum' function facilitates the creation of enums entirely in\nmemory using as close to a \"C style\" as PowerShell will allow.\n\n.PARAMETER Module\n\nThe in-memory module that will host the enum. Use\nNew-InMemoryModule to define an in-memory module.\n\n.PARAMETER FullName\n\nThe fully-qualified name of the enum.\n\n.PARAMETER Type\n\nThe type of each enum element.\n\n.PARAMETER EnumElements\n\nA hashtable of enum elements.\n\n.PARAMETER Bitfield\n\nSpecifies that the enum should be treated as a bitfield.\n\n.EXAMPLE\n\n$Mod = New-InMemoryModule -ModuleName Win32\n\n$ImageSubsystem = psenum $Mod PE.IMAGE_SUBSYSTEM UInt16 @{\n    UNKNOWN =                  0\n    NATIVE =                   1 # Image doesn't require a subsystem.\n    WINDOWS_GUI =              2 # Image runs in the Windows GUI subsystem.\n    WINDOWS_CUI =              3 # Image runs in the Windows character subsystem.\n    OS2_CUI =                  5 # Image runs in the OS/2 character subsystem.\n    POSIX_CUI =                7 # Image runs in the Posix character subsystem.\n    NATIVE_WINDOWS =           8 # Image is a native Win9x driver.\n    WINDOWS_CE_GUI =           9 # Image runs in the Windows CE subsystem.\n    EFI_APPLICATION =          10\n    EFI_BOOT_SERVICE_DRIVER =  11\n    EFI_RUNTIME_DRIVER =       12\n    EFI_ROM =                  13\n    XBOX =                     14\n    WINDOWS_BOOT_APPLICATION = 16\n}\n\n.NOTES\n\nPowerShell purists may disagree with the naming of this function but\nagain, this was developed in such a way so as to emulate a \"C style\"\ndefinition as closely as possible. Sorry, I'm not going to name it\nNew-Enum. :P\n#>\n\n    [OutputType([Type])]\n    Param\n    (\n        [Parameter(Position = 0, Mandatory = $True)]\n        [ValidateScript({($_ -is [Reflection.Emit.ModuleBuilder]) -or ($_ -is [Reflection.Assembly])})]\n        $Module,\n\n        [Parameter(Position = 1, Mandatory = $True)]\n        [ValidateNotNullOrEmpty()]\n        [String]\n        $FullName,\n\n        [Parameter(Position = 2, Mandatory = $True)]\n        [Type]\n        $Type,\n\n        [Parameter(Position = 3, Mandatory = $True)]\n        [ValidateNotNullOrEmpty()]\n        [Hashtable]\n        $EnumElements,\n\n        [Switch]\n        $Bitfield\n    )\n\n    if ($Module -is [Reflection.Assembly])\n    {\n        return ($Module.GetType($FullName))\n    }\n\n    $EnumType = $Type -as [Type]\n\n    $EnumBuilder = $Module.DefineEnum($FullName, 'Public', $EnumType)\n\n    if ($Bitfield)\n    {\n        $FlagsConstructor = [FlagsAttribute].GetConstructor(@())\n        $FlagsCustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($FlagsConstructor, @())\n        $EnumBuilder.SetCustomAttribute($FlagsCustomAttribute)\n    }\n\n    foreach ($Key in $EnumElements.Keys)\n    {\n        # Apply the specified enum type to each element\n        $null = $EnumBuilder.DefineLiteral($Key, $EnumElements[$Key] -as $EnumType)\n    }\n\n    $EnumBuilder.CreateType()\n}\n\n\n# A helper function used to reduce typing while defining struct\n# fields.\nfunction field\n{\n    Param\n    (\n        [Parameter(Position = 0, Mandatory = $True)]\n        [UInt16]\n        $Position,\n        \n        [Parameter(Position = 1, Mandatory = $True)]\n        [Type]\n        $Type,\n        \n        [Parameter(Position = 2)]\n        [UInt16]\n        $Offset,\n        \n        [Object[]]\n        $MarshalAs\n    )\n\n    @{\n        Position = $Position\n        Type = $Type -as [Type]\n        Offset = $Offset\n        MarshalAs = $MarshalAs\n    }\n}\n\n\nfunction struct\n{\n<#\n.SYNOPSIS\n\nCreates an in-memory struct for use in your PowerShell session.\n\nAuthor: Matthew Graeber (@mattifestation)\nLicense: BSD 3-Clause\nRequired Dependencies: None\nOptional Dependencies: field\n \n.DESCRIPTION\n\nThe 'struct' function facilitates the creation of structs entirely in\nmemory using as close to a \"C style\" as PowerShell will allow. Struct\nfields are specified using a hashtable where each field of the struct\nis comprosed of the order in which it should be defined, its .NET\ntype, and optionally, its offset and special marshaling attributes.\n\nOne of the features of 'struct' is that after your struct is defined,\nit will come with a built-in GetSize method as well as an explicit\nconverter so that you can easily cast an IntPtr to the struct without\nrelying upon calling SizeOf and/or PtrToStructure in the Marshal\nclass.\n\n.PARAMETER Module\n\nThe in-memory module that will host the struct. Use\nNew-InMemoryModule to define an in-memory module.\n\n.PARAMETER FullName\n\nThe fully-qualified name of the struct.\n\n.PARAMETER StructFields\n\nA hashtable of fields. Use the 'field' helper function to ease\ndefining each field.\n\n.PARAMETER PackingSize\n\nSpecifies the memory alignment of fields.\n\n.PARAMETER ExplicitLayout\n\nIndicates that an explicit offset for each field will be specified.\n\n.EXAMPLE\n\n$Mod = New-InMemoryModule -ModuleName Win32\n\n$ImageDosSignature = psenum $Mod PE.IMAGE_DOS_SIGNATURE UInt16 @{\n    DOS_SIGNATURE =    0x5A4D\n    OS2_SIGNATURE =    0x454E\n    OS2_SIGNATURE_LE = 0x454C\n    VXD_SIGNATURE =    0x454C\n}\n\n$ImageDosHeader = struct $Mod PE.IMAGE_DOS_HEADER @{\n    e_magic =    field 0 $ImageDosSignature\n    e_cblp =     field 1 UInt16\n    e_cp =       field 2 UInt16\n    e_crlc =     field 3 UInt16\n    e_cparhdr =  field 4 UInt16\n    e_minalloc = field 5 UInt16\n    e_maxalloc = field 6 UInt16\n    e_ss =       field 7 UInt16\n    e_sp =       field 8 UInt16\n    e_csum =     field 9 UInt16\n    e_ip =       field 10 UInt16\n    e_cs =       field 11 UInt16\n    e_lfarlc =   field 12 UInt16\n    e_ovno =     field 13 UInt16\n    e_res =      field 14 UInt16[] -MarshalAs @('ByValArray', 4)\n    e_oemid =    field 15 UInt16\n    e_oeminfo =  field 16 UInt16\n    e_res2 =     field 17 UInt16[] -MarshalAs @('ByValArray', 10)\n    e_lfanew =   field 18 Int32\n}\n\n# Example of using an explicit layout in order to create a union.\n$TestUnion = struct $Mod TestUnion @{\n    field1 = field 0 UInt32 0\n    field2 = field 1 IntPtr 0\n} -ExplicitLayout\n\n.NOTES\n\nPowerShell purists may disagree with the naming of this function but\nagain, this was developed in such a way so as to emulate a \"C style\"\ndefinition as closely as possible. Sorry, I'm not going to name it\nNew-Struct. :P\n#>\n\n    [OutputType([Type])]\n    Param\n    (\n        [Parameter(Position = 1, Mandatory = $True)]\n        [ValidateScript({($_ -is [Reflection.Emit.ModuleBuilder]) -or ($_ -is [Reflection.Assembly])})]\n        $Module,\n\n        [Parameter(Position = 2, Mandatory = $True)]\n        [ValidateNotNullOrEmpty()]\n        [String]\n        $FullName,\n\n        [Parameter(Position = 3, Mandatory = $True)]\n        [ValidateNotNullOrEmpty()]\n        [Hashtable]\n        $StructFields,\n\n        [Reflection.Emit.PackingSize]\n        $PackingSize = [Reflection.Emit.PackingSize]::Unspecified,\n\n        [Switch]\n        $ExplicitLayout\n    )\n\n    if ($Module -is [Reflection.Assembly])\n    {\n        return ($Module.GetType($FullName))\n    }\n\n    [Reflection.TypeAttributes] $StructAttributes = 'AnsiClass,\n        Class,\n        Public,\n        Sealed,\n        BeforeFieldInit'\n\n    if ($ExplicitLayout)\n    {\n        $StructAttributes = $StructAttributes -bor [Reflection.TypeAttributes]::ExplicitLayout\n    }\n    else\n    {\n        $StructAttributes = $StructAttributes -bor [Reflection.TypeAttributes]::SequentialLayout\n    }\n\n    $StructBuilder = $Module.DefineType($FullName, $StructAttributes, [ValueType], $PackingSize)\n    $ConstructorInfo = [Runtime.InteropServices.MarshalAsAttribute].GetConstructors()[0]\n    $SizeConst = @([Runtime.InteropServices.MarshalAsAttribute].GetField('SizeConst'))\n\n    $Fields = New-Object Hashtable[]($StructFields.Count)\n\n    # Sort each field according to the orders specified\n    # Unfortunately, PSv2 doesn't have the luxury of the\n    # hashtable [Ordered] accelerator.\n    foreach ($Field in $StructFields.Keys)\n    {\n        $Index = $StructFields[$Field]['Position']\n        $Fields[$Index] = @{FieldName = $Field; Properties = $StructFields[$Field]}\n    }\n\n    foreach ($Field in $Fields)\n    {\n        $FieldName = $Field['FieldName']\n        $FieldProp = $Field['Properties']\n\n        $Offset = $FieldProp['Offset']\n        $Type = $FieldProp['Type']\n        $MarshalAs = $FieldProp['MarshalAs']\n\n        $NewField = $StructBuilder.DefineField($FieldName, $Type, 'Public')\n\n        if ($MarshalAs)\n        {\n            $UnmanagedType = $MarshalAs[0] -as ([Runtime.InteropServices.UnmanagedType])\n            if ($MarshalAs[1])\n            {\n                $Size = $MarshalAs[1]\n                $AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($ConstructorInfo,\n                    $UnmanagedType, $SizeConst, @($Size))\n            }\n            else\n            {\n                $AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($ConstructorInfo, [Object[]] @($UnmanagedType))\n            }\n            \n            $NewField.SetCustomAttribute($AttribBuilder)\n        }\n\n        if ($ExplicitLayout) { $NewField.SetOffset($Offset) }\n    }\n\n    # Make the struct aware of its own size.\n    # No more having to call [Runtime.InteropServices.Marshal]::SizeOf!\n    $SizeMethod = $StructBuilder.DefineMethod('GetSize',\n        'Public, Static',\n        [Int],\n        [Type[]] @())\n    $ILGenerator = $SizeMethod.GetILGenerator()\n    # Thanks for the help, Jason Shirk!\n    $ILGenerator.Emit([Reflection.Emit.OpCodes]::Ldtoken, $StructBuilder)\n    $ILGenerator.Emit([Reflection.Emit.OpCodes]::Call,\n        [Type].GetMethod('GetTypeFromHandle'))\n    $ILGenerator.Emit([Reflection.Emit.OpCodes]::Call,\n        [Runtime.InteropServices.Marshal].GetMethod('SizeOf', [Type[]] @([Type])))\n    $ILGenerator.Emit([Reflection.Emit.OpCodes]::Ret)\n\n    # Allow for explicit casting from an IntPtr\n    # No more having to call [Runtime.InteropServices.Marshal]::PtrToStructure!\n    $ImplicitConverter = $StructBuilder.DefineMethod('op_Implicit',\n        'PrivateScope, Public, Static, HideBySig, SpecialName',\n        $StructBuilder,\n        [Type[]] @([IntPtr]))\n    $ILGenerator2 = $ImplicitConverter.GetILGenerator()\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Nop)\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ldarg_0)\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ldtoken, $StructBuilder)\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Call,\n        [Type].GetMethod('GetTypeFromHandle'))\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Call,\n        [Runtime.InteropServices.Marshal].GetMethod('PtrToStructure', [Type[]] @([IntPtr], [Type])))\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Unbox_Any, $StructBuilder)\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ret)\n\n    $StructBuilder.CreateType()\n}\n#endregion PSReflect\n\n#region Windows API Definitions\n$Mod = New-InMemoryModule -ModuleName NetworkConnection\n\n#region Enums\n$TCP_TABLE_CLASS = psenum $Mod TCP_TABLE_CLASS UInt16 @{\n    TCP_TABLE_BASIC_LISTENER = 0\n    TCP_TABLE_BASIC_CONNECTIONS = 1\n    TCP_TABLE_BASIC_ALL = 2\n    TCP_TABLE_OWNER_PID_LISTENER = 3\n    TCP_TABLE_OWNER_PID_CONNECTIONS = 4\n    TCP_TABLE_OWNER_PID_ALL = 5\n    TCP_TABLE_OWNER_MODULE_LISTENER = 6\n    TCP_TABLE_OWNER_MODULE_CONNECTIONS = 7\n    TCP_TABLE_OWNER_MODULE_ALL = 8\n}\n\n$TCP_STATE = psenum $Mod TCP_STATE UInt16 @{\n    CLOSED = 1\n    LISTENING = 2\n    SYN_SENT = 3\n    SYN_RECEIVED = 4\n    ESTABLISHED = 5\n    FIN_WAIT1 = 6\n    FIN_WAIT2 = 7\n    CLOSE_WAIT = 8\n    CLOSING = 9\n    LAST_ACK = 10\n    TIME_WAIT = 11\n    DELETE_TCB = 12\n}\n\n$UDP_TABLE_CLASS = psenum $Mod UDP_TABLE_CLASS UInt16 @{\n    UDP_TABLE_BASIC = 0\n    UDP_TABLE_OWNER_PID = 1\n    UDP_TABLE_OWNER_MODULE = 2\n}\n\n$TAG_INFO_LEVEL = psenum $Mod TAG_INFO_LEVEL UInt16 @{\n    eTagInfoLevelNameFromTag = 1\n    eTagInfoLevelNamesReferencingModule = 2\n    eTagInfoLevelNameTagMapping = 3\n    eTagInfoLevelMax = 4\n}\n\n$SC_SERVICE_TAG_QUERY_TYPE = psenum $Mod SC_SERVICE_TAG_QUERY_TYPE UInt16 @{\n    ServiceNameFromTagInformation = 1\n    ServiceNamesReferencingModuleInformation = 2\n    ServiceNameTagMappingInformation = 3\n}\n#endregion Enums\n\n#region Structs\n\n$MIB_UDPROW_OWNER_MODULE = struct $Mod MIB_UDPROW_OWNER_MODULE @{\n    LocalAddr        = field 0 UInt32 0\n    LocalPort        = field 1 UInt32 4\n    OwningPid        = field 2 UInt32 8\n    CreateTimestamp  = field 3 UInt64 16\n    SpecificPortBind = field 4 UInt32 24  # Union\n    Flags            = field 5 UInt32 24\n    OwningModuleInfo = field 6 UInt64[] -MarshalAs @('ByValArray', 16) 32\n} -ExplicitLayout\n\n$MIB_UDP6ROW_OWNER_MODULE = struct $Mod MIB_UDP6ROW_OWNER_MODULE @{\n    LocalAddr        = field 0 Byte[] -MarshalAs @('ByValArray', 16) 0\n    LocalScopeId   = field 1 UInt32 16\n    LocalPort      = field 2 UInt32 20\n    OwningPid      = field 3 UInt32 24\n    CreateTimestamp  = field 4 UInt64 32\n    SpecificPortBind = field 5 UInt32 40  # Union\n    Flags            = field 6 UInt32 40\n    OwningModuleInfo = field 7 UInt64[] -MarshalAs @('ByValArray', 16) 48\n} -ExplicitLayout\n\n\n$MIB_UDPTABLE_OWNER_MODULE = struct $Mod MIB_UDPTABLE_OWNER_MODULE @{\n    NumEntries = field 0 UInt32\n    Table      = field 1 $MIB_UDPROW_OWNER_MODULE\n}\n\n$MIB_UDP6TABLE_OWNER_MODULE = struct $Mod MIB_UDP6TABLE_OWNER_MODULE @{\n    NumEntries = field 0 UInt32\n    Table      = field 1 $MIB_UDPROW_OWNER_MODULE\n}\n\n$MIB_TCPROW_OWNER_MODULE = struct $Mod MIB_TCPROW_OWNER_MODULE @{\n    State           = field 0 $TCP_STATE\n    LocalAddr       = field 1 UInt32\n    LocalPort       = field 2 UInt32\n    RemoteAddr      = field 3 UInt32\n    RemotePort      = field 4 UInt32\n    OwningPid       = field 5 UInt32\n    CreateTimestamp = field 6 UInt64\n    OwningModuleInfo = field 7 UInt64[] -MarshalAs @('ByValArray', 16)\n}\n\n$MIB_TCP6ROW_OWNER_MODULE = struct $Mod MIB_TCP6ROW_OWNER_MODULE @{\n    LocalAddr        = field 0 Byte[] -MarshalAs @('ByValArray', 16)\n    LocalScopeId     = field 1 UInt32\n    LocalPort        = field 2 UInt32\n    RemoteAddr       = field 3 Byte[] -MarshalAs @('ByValArray', 16)\n    RemoteScopeId    = field 4 UInt32\n    RemotePort       = field 5 UInt32\n    State            = field 6 $TCP_STATE\n    OwningPid        = field 7 UInt32\n    CreateTimestamp  = field 8 UInt64\n    OwningModuleInfo = field 9 UInt64[] -MarshalAs @('ByValArray', 16)\n}\n\n$MIB_TCPTABLE_OWNER_MODULE = struct $Mod MIB_TCPTABLE_OWNER_MODULE @{\n    NumEntries = field 0 UInt32\n    Table      = field 1 $MIB_TCPROW_OWNER_MODULE\n}\n\n$MIB_TCP6TABLE_OWNER_MODULE = struct $Mod MIB_TCP6TABLE_OWNER_MODULE @{\n    NumEntries = field 0 UInt32\n    Table      = field 1 $MIB_TCP6ROW_OWNER_MODULE\n}\n\n$SC_SERVICE_TAG_QUERY = struct $Mod SC_SERVICE_TAG_QUERY @{\n    ProcessId = field 0 UInt32\n    ServiceTag = field 1 UInt32\n    Unknown = field 2 UInt32\n    Buffer = field 3 IntPtr\n}\n\n#endregion Structs\n\n#region FunctionDefinitions\n$FunctionDefinitions = @(\n    (func iphlpapi GetExtendedTcpTable ([UInt32]) @([IntPtr], [Int32].MakeByRefType(), [Bool], [Int32], [Int32], [Int32]))\n    (func iphlpapi GetExtendedUdpTable ([UInt32]) @([IntPtr], [Int32].MakeByRefType(), [Bool], [Int32], [Int32], [Int32]))\n    (func advapi32 I_QueryTagInformation ([UInt32]) @([IntPtr], $SC_SERVICE_TAG_QUERY_TYPE, $SC_SERVICE_TAG_QUERY.MakeByRefType()))\n)\n\n$Types = $FunctionDefinitions | Add-Win32Type -Module $Mod -Namespace 'NetworkConnection'\n$IPHelperAPI = $Types['iphlpapi']\n$Advapi32 = $Types['advapi32']\n\n#endregion FunctionDefinitions\n\n#region Helper Functions\n\nfunction Get-ServiceNameFromTag($ProcessId, $ServiceTag)\n{\n    $NTVersion = [System.Environment]::OSVersion.Version\n\n    if($NTVersion.Major -ge 6 -and $NTVersion.Minor -ge 1)\n    {\n        # Based off of https://wj32.org/wp/2010/03/30/howto-use-i_querytaginformation/\n        $ServiceTagQuery = [Activator]::CreateInstance($SC_SERVICE_TAG_QUERY)   # New-Object doesn't work on PSv2 for some reason.  Thanks @mattifestation! \n        $ServiceTagQuery.ProcessId = $ProcessId\n        $ServiceTagQuery.ServiceTag = $ServiceTag\n    \n        $Res = $Advapi32::I_QueryTagInformation([IntPtr]::Zero, $SC_SERVICE_TAG_QUERY_TYPE::ServiceNameFromTagInformation, [Ref] $ServiceTagQuery)\n        \n        if($Res -eq 0)\n        {\n            $ServiceStr = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($ServiceTagQuery.Buffer)\n            $ServiceStr\n        }\n        else {\n            #\"Error: $Res\"\n        }\n    }\n}\n\nfunction Get-Tcp4Connections\n{\n    Param\n    (\n        # Attempt to resolve the hostnames of each IP address\n        [switch]\n        $ResolveHostnames,\n\n        [switch]\n        $ReturnHashTables\n    )\n\n    $AF_INET = 2\n    $TableBufferSize = 0\n    $null = $IPHelperAPI::GetExtendedTcpTable([IntPtr]::Zero, [ref]$TableBufferSize, $true, $AF_INET, $TCP_TABLE_CLASS::TCP_TABLE_OWNER_MODULE_ALL, 0)\n    $TableBuffer = [Runtime.InteropServices.Marshal]::AllocHGlobal($TableBufferSize)\n    \n    try\n    {\n        $Ret = $IPHelperAPI::GetExtendedTcpTable($TableBuffer, [ref] $TableBufferSize, $true, $AF_INET, $TCP_TABLE_CLASS::TCP_TABLE_OWNER_MODULE_ALL, 0);\n        if ($Ret -ne 0)\n        {\n            Write-Error \"Failed to get TCP connection information. GetExtendedTcpTable's return code: $Ret\"\n            return\n        }\n        \n        $OwnerModuleTable  = $TableBuffer -as $MIB_TCPTABLE_OWNER_MODULE\n        $RowPtr = [IntPtr]($TableBuffer.ToInt64() + [Runtime.InteropServices.Marshal]::OffsetOf($MIB_TCPTABLE_OWNER_MODULE, \"Table\").ToInt64())\n        \n        for($i=0; $i -lt $OwnerModuleTable.NumEntries; $i++)\n        {\n            $TcpRow = $RowPtr -as $MIB_TCPROW_OWNER_MODULE\n\n            # Get the properties we want\n            $LocalAddr = [System.Net.IPAddress]$TcpRow.LocalAddr\n            $PortBytes = [System.BitConverter]::GetBytes($TcpRow.LocalPort)\n            $LocalPort = $PortBytes[0]*256 + $PortBytes[1]\n\n            $RemoteAddr = [System.Net.IPAddress]$TcpRow.RemoteAddr\n            $PortBytes = [System.BitConverter]::GetBytes($TcpRow.RemotePort)\n            $RemotePort = $PortBytes[0]*256 + $PortBytes[1]\n\n            $ServiceTag = $TcpRow.OwningModuleInfo[0]                \n\n            $RemoteHostname = $null\n            if($ResolveHostnames) {\n                try {\n                    $RemoteHostname = [System.Net.Dns]::GetHostEntry($RemoteAddr).HostName\n                }\n                catch {\n                    # Couldn't resolve the host name, so keep the IP\n                }\n            }\n\n            $Output = @{\n                LocalAddress = [string]$LocalAddr\n                LocalPort = $LocalPort\n                RemoteAddress = [string]$RemoteAddr\n                RemoteHostname = $RemoteHostname\n                RemotePort = $RemotePort\n                #Process = Get-Process -Id $TcpRow.OwningPid -ErrorAction SilentlyContinue\n                Process = (Get-Process -Id $TcpRow.OwningPid -ErrorAction SilentlyContinue).Name\n                ProcessId = $TcpRow.OwningPid\n                Protocol = \"TCP\"\n                State = $TcpRow.State.ToString()\n                Service = [string](Get-ServiceNameFromTag -ProcessId $TcpRow.OwningPid -ServiceTag $ServiceTag)\n            }\n\n            if($ReturnHashtables) {\n                $Output\n            } else {\n                New-Object PSObject -Property $Output \n            }\n\n            # Move to the next row in the TCP table\n            $RowPtr = [IntPtr]($RowPtr.ToInt64() + [Runtime.InteropServices.Marshal]::SizeOf($TcpRow))\n        }\n    }\n    catch\n    {\n        Write-Error $_\n    }\n    finally\n    {\n        [Runtime.InteropServices.Marshal]::FreeHGlobal($TableBuffer)\n    }\n}\n\nfunction Get-Tcp6Connections\n{\n    Param\n    (\n        # Attempt to resolve the hostnames of each IP address\n        [switch]\n        $ResolveHostnames,\n\n        [switch]\n        $ReturnHashTables\n    )\n\n    $AF_INET6 = 23\n    $TableBufferSize = 0\n        \n    $null = $IPHelperAPI::GetExtendedTcpTable([IntPtr]::Zero, [ref]$TableBufferSize, $true, $AF_INET6, $TCP_TABLE_CLASS::TCP_TABLE_OWNER_MODULE_ALL, 0)\n    $TableBuffer = [Runtime.InteropServices.Marshal]::AllocHGlobal($TableBufferSize)\n        \n    try\n    {\n        $Ret = $IPHelperAPI::GetExtendedTcpTable($TableBuffer, [ref] $TableBufferSize, $true, $AF_INET6, $TCP_TABLE_CLASS::TCP_TABLE_OWNER_MODULE_ALL, 0);\n            \n        if($Ret -eq 50)\n        {\n            # IPv6 is not supported\n            return\n        }\n        elseif ($Ret -ne 0)\n        {\n            Write-Error \"Failed to get TCP connection information. GetExtendedTcpTable's return code: $Ret\"\n            return\n        }\n        \n        $OwnerModuleTable  = $TableBuffer -as $MIB_TCP6TABLE_OWNER_MODULE\n        $RowPtr = [IntPtr]($TableBuffer.ToInt64() + [Runtime.InteropServices.Marshal]::OffsetOf($MIB_TCPTABLE_OWNER_MODULE, \"Table\").ToInt64())\n\n        for($i=0; $i -lt $OwnerModuleTable.NumEntries; $i++)\n        {\n            $TcpRow = $RowPtr -as $MIB_TCP6ROW_OWNER_MODULE\n            \n            # Get the properties we want\n            $LocalAddr = [System.Net.IPAddress]$TcpRow.LocalAddr\n            $PortBytes = [System.BitConverter]::GetBytes($TcpRow.LocalPort)\n            $LocalPort = $PortBytes[0]*256 + $PortBytes[1]\n            \n            $RemoteAddr = [System.Net.IPAddress]$TcpRow.RemoteAddr\n            $PortBytes = [System.BitConverter]::GetBytes($TcpRow.RemotePort)\n            $RemotePort = $PortBytes[0]*256 + $PortBytes[1]\n\n            $ServiceTag = $TcpRow.OwningModuleInfo[0]\n\n            $RemoteHostname = $null;\n            if($ResolveHostnames) {\n                try {\n                    $RemoteHostname = [System.Net.Dns]::GetHostEntry($RemoteAddr).HostName\n                }\n                catch {\n                    # Couldn't resolve the host name, so keep the IP\n                }\n            }\n\n            $Output = @{\n                LocalAddress = [string]$LocalAddr\n                LocalPort = $LocalPort\n                RemoteAddress = [string]$RemoteAddr\n                RemoteHostname = $RemoteHostname\n                RemotePort = $RemotePort\n                Process = (Get-Process -Id $TcpRow.OwningPid -ErrorAction SilentlyContinue).Name\n                ProcessId = $TcpRow.OwningPid\n                Protocol = \"TCP\"\n                State = $TcpRow.State.ToString()\n                Service = [string](Get-ServiceNameFromTag -ProcessId $TcpRow.OwningPid -ServiceTag $ServiceTag)\n            }\n\n            if($ReturnHashtables) {\n                $Output\n            } else {\n                New-Object PSObject -Property $Output \n            }\n\n            # Move to the next row in the TCP table\n            $RowPtr = [IntPtr]($RowPtr.ToInt64() + [Runtime.InteropServices.Marshal]::SizeOf($TcpRow))\n        }\n    }\n    catch\n    {\n        Write-Error $_\n    }\n    finally\n    {\n        [Runtime.InteropServices.Marshal]::FreeHGlobal($TableBuffer)\n    }\n}\n\nfunction Get-Udp4Connections\n{\n    Param\n    (\n        # Attempt to resolve the hostnames of each IP address\n        [switch]\n        $ResolveHostnames,\n\n        [switch]\n        $ReturnHashTables\n    )\n\n    $AF_INET = 2\n    $TableBufferSize = 0\n    $null = $IPHelperAPI::GetExtendedUdpTable([IntPtr]::Zero, [ref]$TableBufferSize, $true, $AF_INET, $UDP_TABLE_CLASS::UDP_TABLE_OWNER_MODULE, 0)\n    $TableBuffer = [Runtime.InteropServices.Marshal]::AllocHGlobal($TableBufferSize)\n\n    try\n    {\n        $Ret = $IPHelperAPI::GetExtendedUdpTable($TableBuffer, [ref] $TableBufferSize, $true, $AF_INET, $UDP_TABLE_CLASS::UDP_TABLE_OWNER_MODULE, 0);\n        if ($Ret -ne 0)\n        {\n            Write-Error \"Failed to get UDP connection information. GetExtendedUdpTable's return code: $Ret\"\n            return\n        }\n        \n        $OwnerModuleTable  = $TableBuffer -as $MIB_UDPTABLE_OWNER_MODULE\n        $RowPtr = [IntPtr]($TableBuffer.ToInt64() + [Runtime.InteropServices.Marshal]::OffsetOf($MIB_UDPTABLE_OWNER_MODULE, \"Table\").ToInt64())\n\n        for($i=0; $i -lt $OwnerModuleTable.NumEntries; $i++)\n        {\n            $UdpRow = $RowPtr -as $MIB_UDPROW_OWNER_MODULE\n\n            # Get the properties we want\n            $LocalAddr = [System.Net.IPAddress]$UdpRow.LocalAddr\n            $PortBytes = [System.BitConverter]::GetBytes($UdpRow.LocalPort)\n            $LocalPort = $PortBytes[0]*256 + $PortBytes[1]\n            $ServiceTag = $UdpRow.OwningModuleInfo[0]\n\n            $Output = @{\n                LocalAddress = [string]$LocalAddr\n                LocalPort = $LocalPort\n                Process = (Get-Process -Id $UdpRow.OwningPid -ErrorAction SilentlyContinue).Name\n                ProcessId = $UdpRow.OwningPid\n                Protocol = \"UDP\"\n                Service = [string](Get-ServiceNameFromTag -ProcessId $UdpRow.OwningPid -ServiceTag $ServiceTag)\n            }\n\n            if($ReturnHashtables) {\n                $Output\n            } else {\n                New-Object PSObject -Property $Output \n            }\n\n            # Move to the next row in the UDP table\n            $RowPtr = [IntPtr]($RowPtr.ToInt64() + ([Runtime.InteropServices.Marshal]::SizeOf($UdpRow)))\n        }\n    }\n    catch\n    {\n        Write-Error $_\n    }\n    finally\n    {\n        [Runtime.InteropServices.Marshal]::FreeHGlobal($TableBuffer)\n    }\n}\n\nfunction Get-Udp6Connections\n{\n    Param\n    (\n        # Attempt to resolve the hostnames of each IP address\n        [switch]\n        $ResolveHostnames,\n\n        [switch]\n        $ReturnHashTables\n    )\n\n    $AF_INET6 = 23\n    $TableBufferSize = 0\n    $null = $IPHelperAPI::GetExtendedUdpTable([IntPtr]::Zero, [ref]$TableBufferSize, $true, $AF_INET6, $UDP_TABLE_CLASS::UDP_TABLE_OWNER_MODULE, 0)\n    $TableBuffer = [Runtime.InteropServices.Marshal]::AllocHGlobal($TableBufferSize)\n\n    try\n    {\n        $Ret = $IPHelperAPI::GetExtendedUdpTable($TableBuffer, [ref] $TableBufferSize, $true, $AF_INET6, $UDP_TABLE_CLASS::UDP_TABLE_OWNER_MODULE, 0);\n        if($Ret -eq 50) # ERROR_NOT_SUPPORTED\n        {\n            # IPv6 is not supported\n            return\n        }\n        elseif ($Ret -ne 0)\n        {\n            Write-Error \"Failed to get TCP connection information. GetExtendedTcpTable's return code: $Ret\"\n            return\n        }\n        \n        $OwnerModuleTable  = $TableBuffer -as $MIB_UDP6TABLE_OWNER_MODULE\n        $RowPtr = [IntPtr]($TableBuffer.ToInt64() + [Runtime.InteropServices.Marshal]::OffsetOf($MIB_UDPTABLE_OWNER_MODULE, \"Table\").ToInt64())\n  \n        for($i=0; $i -lt $OwnerModuleTable.NumEntries; $i++)\n        {\n            $UdpRow = $RowPtr -as $MIB_UDP6ROW_OWNER_MODULE\n\n            $LocalAddr = [System.Net.IPAddress]$UdpRow.LocalAddr\n            $PortBytes = [System.BitConverter]::GetBytes($UdpRow.LocalPort)\n            $LocalPort = $PortBytes[0]*256 + $PortBytes[1]\n            $ServiceTag = $UdpRow.OwningModuleInfo[0]\n\n            if($ResolveHostnames) {\n                try {\n                    $RemoteIP = [System.Net.Dns]::GetHostEntry($LocalAddr).HostName\n                }\n                catch {\n\n                }\n            }\n\n            $Output = @{\n                LocalAddress = [string]$LocalAddr\n                LocalPort = $LocalPort\n                Process = (Get-Process -Id $UdpRow.OwningPid -ErrorAction SilentlyContinue).Name\n                ProcessId = $UdpRow.OwningPid\n                Protocol = \"UDP\"\n                Service = [string](Get-ServiceNameFromTag -ProcessId $UdpRow.OwningPid -ServiceTag $ServiceTag)\n            }\n\n            if($ReturnHashtables) {\n                $Output\n            } else {\n                New-Object PSObject -Property $Output \n            }\n\n            # Move to the next row in the UDP table\n            $RowPtr = [IntPtr]($RowPtr.ToInt64() + ([Runtime.InteropServices.Marshal]::SizeOf($UdpRow)))\n        }\n    }\n    catch\n    {\n        Write-Error $_\n    }\n    finally\n    {\n        [Runtime.InteropServices.Marshal]::FreeHGlobal($TableBuffer)\n    }\n}\n\n#endregion Helper Functions\n\nStart-AceScript -Uri https://10.182.18.200 -SweepId $args[0] -ScanId ([Guid]::NewGuid()) -RoutingKey siem -Thumbprint 8D1DB3B7B85B6F9E9DE87B291DF66692A10240AE"
  },
  {
    "path": "ACE-Management/PS-ACE/Scripts/ACE_Get-PSAutorun.ps1",
    "content": "﻿Function Get-PSAutorun {\n<#\n    .SYNOPSIS\n        Get Autorun entries.\n     \n    .DESCRIPTION\n        Retrieve a list of programs configured to autostart at boot or logon.\n      \n    .PARAMETER All\n        Switch to gather artifacts from all categories. \n        If it's turned on, all other category switches will be ignored.\n      \n    .PARAMETER BootExecute\n        Switch to gather artifacts from the Boot Execute category.\n\n    .PARAMETER AppinitDLLs\n        Switch to gather artifacts from the Appinit category.\n    \n    .PARAMETER ExplorerAddons\n        Switch to gather artifacts from the Explorer category.\n\n    .PARAMETER SidebarGadgets\n        Switch to gather artifacts from the Sidebar Gadgets category.\n\n    .PARAMETER ImageHijacks\n        Switch to gather artifacts from the Image Hijacks category.\n\n    .PARAMETER InternetExplorerAddons\n        Switch to gather artifacts from the Intenet Explorer category.\n\n    .PARAMETER KnownDLLs\n        Switch to gather artifacts from the KnownDLLs category.\n\n    .PARAMETER Logon\n        Switch to gather artifacts from the Logon category.\n\n    .PARAMETER Winsock\n        Switch to gather artifacts from the Winsock and network providers category.\n\n    .PARAMETER Codecs\n        Switch to gather artifacts from the Codecs category.\n\n    .PARAMETER OfficeAddins\n        Switch to gather artifacts from Office Addins\n\n    .PARAMETER PrintMonitorDLLs\n        Switch to gather artifacts from the Print Monitors category.\n\n    .PARAMETER LSAsecurityProviders\n        Switch to gather artifacts from the LSA Providers category.\n\n    .PARAMETER ServicesAndDrivers\n        Switch to gather artifacts from the Services and Drivers categories.\n\n    .PARAMETER ScheduledTasks\n        Switch to gather artifacts from the Scheduled tasks category.\n\n    .PARAMETER Winlogon\n        Switch to gather artifacts from the Winlogon category.\n\n    .PARAMETER WMI\n        Switch to gather artifacts from the WMI category.\n\n    .PARAMETER ShowFileHash\n        Switch to enable and display MD5, SHA1 and SHA2 file hashes.\n\n    .PARAMETER VerifyDigitalSignature\n        Switch to report if a file is digitally signed with the built-in Get-AuthenticodeSignature cmdlet.\n              \n    .EXAMPLE\n        Get-PSAutorun -BootExecute -AppinitDLLs\n\n    .EXAMPLE\n        Get-PSAutorun -KnownDLLs -LSAsecurityProviders -ShowFileHash\n\n    .EXAMPLE\n         Get-PSAutorun -All -ShowFileHash -VerifyDigitalSignature\n\n#>\n\n    [CmdletBinding()]\n    Param(\n        [switch]$All,\n        [Switch]$BootExecute,\n        [Switch]$AppinitDLLs,\n        [Switch]$ExplorerAddons,\n        [Switch]$SidebarGadgets,\n        [Switch]$ImageHijacks,\n        [Switch]$InternetExplorerAddons,\n        [Switch]$KnownDLLs,\n        [Switch]$Logon,\n        [Switch]$Winsock,\n        [Switch]$Codecs,\n        [Switch]$OfficeAddins,\n        [Switch]$PrintMonitorDLLs,\n        [Switch]$LSAsecurityProviders,\n        [Switch]$ServicesAndDrivers,\n        [Switch]$ScheduledTasks,\n        [Switch]$Winlogon,\n        [Switch]$WMI,\n        [Switch]$ShowFileHash,\n        [Switch]$VerifyDigitalSignature\n    )\n\nBegin {\n\n    #region Helperfunctions\n\n    # Courtesy of Microsoft\n    # Extracted from PS 4.0 with (dir function:\\Get-FileHash).Definition\n    Function Get-FileHash {\n        [CmdletBinding(DefaultParameterSetName = 'Path')]\n        Param(\n            [Parameter(Mandatory, ParameterSetName='Path', Position = 0)]\n            [System.String[]]\n            $Path,\n\n            [Parameter(Mandatory, ParameterSetName='LiteralPath', ValueFromPipelineByPropertyName = $true)]\n            [Alias('PSPath')]\n            [System.String[]]\n            $LiteralPath,\n        \n            [ValidateSet('SHA1', 'SHA256', 'SHA384', 'SHA512', 'MACTripleDES', 'MD5', 'RIPEMD160')]\n            [System.String]\n            $Algorithm='SHA256'\n        )\n    \n        Begin {\n            # Construct the strongly-typed crypto object\n            $hasher = [System.Security.Cryptography.HashAlgorithm]::Create($Algorithm)\n        }\n        Process {\n            $pathsToProcess = @()\n        \n            if($PSCmdlet.ParameterSetName  -eq 'LiteralPath') {\n                $pathsToProcess += Resolve-Path -LiteralPath $LiteralPath | Foreach-Object ProviderPath\n            } else {\n                $pathsToProcess += Resolve-Path $Path | Foreach-Object ProviderPath\n            }\n        \n            foreach($filePath in $pathsToProcess) {\n                if(Test-Path -LiteralPath $filePath -PathType Container) {\n                    continue\n                }\n            \n                try {\n                    # Read the file specified in $FilePath as a Byte array\n                    [system.io.stream]$stream = [system.io.file]::OpenRead($FilePath)\n                \n                    # Compute file-hash using the crypto object\n                    [Byte[]] $computedHash = $hasher.ComputeHash($stream)\n                } catch [Exception] {\n                    $errorMessage = [Microsoft.PowerShell.Commands.UtilityResources]::FileReadError -f $FilePath, $_\n                    Write-Error -Message $errorMessage -Category ReadError -ErrorId 'FileReadError' -TargetObject $FilePath\n                    return\n                } finally {\n                    if($stream) {\n                        $stream.Close()\n                    }\n                }\n                        \n                # Convert to hex-encoded string\n                [string] $hash = [BitConverter]::ToString($computedHash) -replace '-',''\n                \n                $retVal = [PSCustomObject] @{\n                    Algorithm = $Algorithm.ToUpperInvariant()\n                    Hash = $hash\n                    Path = $filePath\n                }\n                $retVal.psobject.TypeNames.Insert(0, 'Microsoft.Powershell.Utility.FileHash')\n                $retVal\n            }\n        }\n    }\n\n    Function Get-RegValue {\n    [CmdletBinding()]\n    Param(\n        [string]$Path,\n        [string[]]$Name,\n        [string]$Category\n    )\n    Begin{\n        if ($Path -match 'Wow6432Node') {\n            $ClassesPath = Join-Path -Path (Split-Path $Path -Qualifier) -ChildPath 'SOFTWARE\\Wow6432Node\\Classes\\CLSID'\n        } else {\n            $ClassesPath = Join-Path -Path (Split-Path $Path -Qualifier) -ChildPath 'SOFTWARE\\Classes\\CLSID'\n        }\n    }\n    Process {\n        try {\n            $Values = Get-Item -LiteralPath $Path -ErrorAction Stop\n            if ($Name -eq '*') {\n                $Name = $Values.GetValueNames()\n            }\n            $Name | ForEach-Object -Process {\n                # Need to differentiate between empty string and really non existing values\n                if ($null -ne $Values.GetValue($_)) {\n                    $Value  = Switch -regex($Values.GetValue($_)) {\n                        '^\\{[A-Z0-9]{4}([A-Z0-9]{4}-){4}[A-Z0-9]{12}\\}$' {\n                            (Get-ItemProperty -Path (Join-Path -Path $ClassesPath -ChildPath \"$($_)\\InprocServer32\") -Name '(default)' -ErrorAction SilentlyContinue).'(default)'\n                            break\n                        }\n                        default {\n                            $_ \n                        }\n                    }\n                    if ($Value) {\n                        @{\n                            Path = $Path\n                            Item = $_\n                            Value = $Value\n                            Category = $Category\n                        }\n                    }\n                }\n            }\n        } catch {\n        }\n    }\n    End {}\n    }\n\n    Function Get-AllScheduledTask {\n        [CmdletBinding()]\n        Param (\n            [Parameter(Mandatory=$false,ValueFromPipeline=$true)]\n            [System.String[]]$ComputerName = $env:COMPUTERNAME\n        )\n        Begin {\n            Function Get-SubFolder ($folder,[switch]$recurse) {\n                $folder\n                if ($recurse) {\n                    $TaskService.GetFolder($folder).GetFolders(0) | ForEach-Object {\n                    Get-SubFolder $_.Path -Recurse\n                    }\n                } else {\n                    $TaskService.GetFolder($folder).GetFolders(0)\n                }\n   \n            }\n        }\n        Process {\n            $ComputerName | ForEach-Object -Process {\n                $alltasks = @()\n                $Computer  = $_\n                $TaskService = New-Object -com schedule.service\n                try {\n                    $null = $TaskService.Connect($Computer)\n\n                } catch {\n                    Write-Warning \"Cannot connect to $Computer because $($_.Exception.Message)\"\n                    return\n                }\n                Get-SubFolder -folder '\\' -recurse | ForEach-Object -Process {\n\n                    $TaskService.GetFolder($_).GetTasks(1) | ForEach-Object -Process {\n                        $obj = New-Object -TypeName pscustomobject -Property @{\n                            ComputerName = $Computer\n                            Path = Split-Path $_.Path\n                            Name = $_.Name\n                        }\n                        $alltasks += $obj\n                    }\n                }\n                Write-Verbose -Message \"There's a total of $($alltasks.Count) tasks on $Computer\"\n                $alltasks\n            }\n        }\n        End {}\n    }\n\n    Function Get-Task {\n    [CmdletBinding()]\n    [OutputType('System.Object[]')]\n        param (\n        [parameter(ValueFromPipeline=$false,ValueFromPipelineByPropertyName=$true,Mandatory=$false)]\n        [system.string[]] ${ComputerName} = $env:computername,\n\n        [parameter(ValueFromPipeline=$false,ValueFromPipelineByPropertyName=$true,Mandatory=$false,\n                    HelpMessage=\"The task folder string must begin by '\\'\")]\n        [ValidatePattern('^\\\\')]\n        [system.string[]] ${Path} = '\\',\n\n        [parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Mandatory=$true)]\n        [ValidateNotNullOrEmpty()]\n        [system.string[]] ${Name} = $null\n        )\n        Begin {}\n        Process\n        {\n            $resultsar = @()\n            $ComputerName | ForEach-Object -Process {\n                $Computer = $_\n                $TaskService = New-Object -com schedule.service\n                try {\n                    $null = $TaskService.Connect($Computer)\n                } catch {\n                    Write-Warning \"Failed to connect to $Computer\"\n                }\n                if ($TaskService.Connected) {\n                    Write-Verbose -Message \"Connected to the scheduler service of computer $Computer\"\n                        Foreach ($Folder in $Path) {\n                            Write-Verbose -Message \"Dealing with folder task $Folder\"\n                            $RootFolder = $null\n                            try {\n                                $RootFolder = $TaskService.GetFolder($Folder)\n                            } catch {\n                                Write-Warning -Message \"The folder task $Folder cannot be found\"\n                            }\n                            if ($RootFolder) {\n                                Foreach ($Task in $Name) {\n                                    $TaskObject = $null\n                                    try {\n                                        Write-Verbose -Message \"Dealing with task name $Task\"\n                                        $TaskObject = $RootFolder.GetTask($Task)\n                                    } catch {\n                                        Write-Warning -Message \"The task $Task cannot be found under $Folder\"\n                                    }\n                                    if ($TaskObject) {\n                                        # Status\n                                        # http://msdn.microsoft.com/en-us/library/windows/desktop/aa383617%28v=vs.85%29.aspx\n                                        switch ($TaskObject.State) {\n                                            0 { $State = 'Unknown'  ; break}\n                                            1 { $State = 'Disabled' ; break}\n                                            2 { $State = 'Queued'   ; break}\n                                            3 { $State = 'Ready'    ; break}\n                                            4 { $State = 'Running'  ; break}\n                                            default {$State = $_ }\n                                        }\n\n                                        $resultsar += New-Object -TypeName pscustomobject -Property @{\n                                            ComputerName = $Computer\n                                            Name = $TaskObject.Name\n                                            Path = $Folder\n                                            State = $State\n                                            Enabled = $TaskObject.Enabled\n                                            Xml = $TaskObject.XML\n\n                                        }\n                                    }\n                                }\n                            }\n                        }\n                }\n            }\n            $resultsar\n        } \n        End {}\n    }\n\n    # From David Wyatt\n    # http://gallery.technet.microsoft.com/scriptcenter/Normalize-file-system-5d33985a\n    Function Get-NormalizedFileSystemPath {\n        <#\n        .Synopsis\n            Normalizes file system paths.\n        .DESCRIPTION\n            Normalizes file system paths.  This is similar to what the Resolve-Path cmdlet does, except Get-NormalizedFileSystemPath also properly handles UNC paths and converts 8.3 short names to long paths.\n        .PARAMETER Path\n            The path or paths to be normalized.\n        .PARAMETER IncludeProviderPrefix\n            If this switch is passed, normalized paths will be prefixed with 'FileSystem::'.  This allows them to be reliably passed to cmdlets such as Get-Content, Get-Item, etc, regardless of Powershell's current location.\n        .EXAMPLE\n            Get-NormalizedFileSystemPath -Path '\\\\server\\share\\.\\SomeFolder\\..\\SomeOtherFolder\\File.txt'\n\n            Returns '\\\\server\\share\\SomeOtherFolder\\File.txt'\n        .EXAMPLE\n            '\\\\server\\c$\\.\\SomeFolder\\..\\PROGRA~1' | Get-NormalizedFileSystemPath -IncludeProviderPrefix\n\n            Assuming you can access the c$ share on \\\\server, and PROGRA~1 is the short name for \"Program Files\" (which is common), returns:\n\n            'FileSystem::\\\\server\\c$\\Program Files'\n        .INPUTS\n            String\n        .OUTPUTS\n            String\n        .NOTES\n            Paths passed to this command cannot contain wildcards; these will be treated as invalid characters by the .NET Framework classes which do the work of validating and normalizing the path.\n        .LINK\n            Resolve-Path\n        #>\n\n        [CmdletBinding()]\n        Param (\n            [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]\n            [Alias('PSPath', 'FullName')]\n            [string[]]\n            $Path,\n\n            [switch]\n            $IncludeProviderPrefix\n        )\n        Process{\n            foreach ($_path in $Path)\n            {\n                $_resolved = $_path\n\n                if ($_resolved -match '^([^:]+)::') {\n                    $providerName = $matches[1]\n\n                    if ($providerName -ne 'FileSystem') {\n                        Write-Error \"Only FileSystem paths may be passed to Get-NormalizedFileSystemPath.  Value '$_path' is for provider '$providerName'.\"\n                        continue\n                    }\n\n                    $_resolved = $_resolved.Substring($matches[0].Length)\n                }\n\n                if (-not [System.IO.Path]::IsPathRooted($_resolved)) {\n                    $_resolved = Join-Path -Path $PSCmdlet.SessionState.Path.CurrentFileSystemLocation -ChildPath $_resolved\n                }\n\n                try {\n                    $dirInfo = New-Object System.IO.DirectoryInfo($_resolved)\n                } catch {\n                    $exception = $_.Exception\n                    while ($null -ne $exception.InnerException) {\n                        $exception = $exception.InnerException\n                    }\n                    Write-Error \"Value '$_path' could not be parsed as a FileSystem path: $($exception.Message)\"\n                    continue\n                }\n    \n                $_resolved = $dirInfo.FullName\n\n                if ($IncludeProviderPrefix) {\n                    $_resolved = \"FileSystem::$_resolved\"\n                }\n                Write-Output $_resolved\n            }\n        } \n    }\n    \n    Function Get-PSRawAutoRun {\n        [CmdletBinding()]\n        Param(\n            [switch]$All,\n            [Switch]$BootExecute,\n            [Switch]$AppinitDLLs,\n            [Switch]$ExplorerAddons,\n            [Switch]$SidebarGadgets,\n            [Switch]$ImageHijacks,\n            [Switch]$InternetExplorerAddons,\n            [Switch]$KnownDLLs,\n            [Switch]$Logon,\n            [Switch]$Winsock,\n            [Switch]$Codecs,\n            [Switch]$OfficeAddins,\n            [Switch]$PrintMonitorDLLs,\n            [Switch]$LSAsecurityProviders,\n            [Switch]$ServicesAndDrivers,\n            [Switch]$ScheduledTasks,\n            [Switch]$Winlogon,\n            [Switch]$WMI,\n            [Switch]$ShowFileHash,\n            [Switch]$VerifyDigitalSignature\n\n        )\n        Begin {\n            ## Add 'All' if nothing else was supplied\n            $parametersToIgnore = (\"ShowFileHash\",\"VerifyDigitalSignature\") +\n                [System.Management.Automation.PSCmdlet]::CommonParameters +\n                [System.Management.Automation.PSCmdlet]::OptionalCommonParameters\n            if(($PSBoundParameters.Keys | ? { $_ -notin $parametersToIgnore }).Count -eq 0)\n            {\n                $All = [switch]::Present\n            }\n        }\n        Process {\n            if ($All -or $BootExecute) {\n                Write-Verbose -Message 'Looking for Boot Execute entries'\n                #region Boot Execute\n\t            $Category = @{ Category = 'Boot Execute'}\n\n                # REG_MULTI_SZ\n\t            'BootExecute','SetupExecute','Execute','S0InitialCommand' | ForEach-Object {\n\t\t            $item = $_\n                    $v = $null\n                    $v = (Get-RegValue -Path 'HKLM:\\System\\CurrentControlSet\\Control\\Session Manager' -Name $_ @Category)\n                    if ($v) {\n                        $v.Value | ForEach-Object {\n                            if ($_ -ne '\"\"') {\n                                [pscustomobject]@{\n                                    Path = 'HKLM:\\System\\CurrentControlSet\\Control\\Session Manager'\n                                    Item = $item\n                                    Value = $_\n                                    Category = 'Boot Execute'\n                                }\n                            }\n                        }\n                    }\n\t            }\n\n\t            Get-RegValue -Path 'HKLM:\\System\\CurrentControlSet\\Control' -Name 'ServiceControlManagerExtension' @Category\n                #endregion Boot Execute\n            }\n            if ($All -or $AppinitDLLs) {\n                Write-Verbose -Message 'Looking for Appinit DLLs entries'\n                #region AppInit\n\t            $null,'Wow6432Node' | Foreach-Object {\n\t\t            Get-RegValue -Path \"HKLM:\\SOFTWARE\\$($_)\\Microsoft\\Windows NT\\CurrentVersion\\Windows\" -Name 'Appinit_Dlls' -Category 'AppInit'\n\t            }\n\n\t            if (Test-Path -Path 'HKLM:\\System\\CurrentControlSet\\Control\\Session Manager\\AppCertDlls' -PathType Container) {\n\t\t            Get-RegValue -Path 'HKLM:\\System\\CurrentControlSet\\Control\\Session Manager\\AppCertDlls' -Name '*' -Category 'AppInit'\n\t            }\n                #endregion AppInit\n            }\n            if ($All -or $ExplorerAddons) {\n                Write-Verbose -Message 'Looking for Explorer Add-ons entries'\n                #region Explorer\n    \n                $Category = @{ Category = 'Explorer'}\n\n                # Filter & Handler\n                'Filter','Handler' | ForEach-Object -Process {\n                    $key = \"HKLM:\\SOFTWARE\\Classes\\Protocols\\$($_)\"\n                    if (Test-Path -Path $key -PathType Container) {\n                        (Get-Item -Path $key).GetSubKeyNames() | ForEach-Object -Process {\n                            if ($_ -eq 'ms-help') {\n                                if ([environment]::Is64BitOperatingSystem) {\n                                    $ClassesPath = 'HKLM:\\SOFTWARE\\Wow6432Node\\Classes\\CLSID'\n                                } else {\n                                    $ClassesPath = 'HKLM:\\SOFTWARE\\Classes\\CLSID'\n                                }\n                                $i = (Get-ItemProperty -Path \"$key\\ms-help\" -Name 'CLSID').CLSID\n                                [pscustomobject]@{\n                                    Path = \"$key\\ms-help\"\n                                    Item = $i\n                                    Value = $(\n                                        (Get-ItemProperty -Path (Join-Path -Path 'HKLM:\\SOFTWARE\\Wow6432Node\\Classes\\CLSID' -ChildPath \"$($i)\\InprocServer32\") -Name '(default)' -ErrorAction SilentlyContinue).'(default)';\n                                        (Get-ItemProperty -Path (Join-Path -Path 'HKLM:\\SOFTWARE\\Classes\\CLSID' -ChildPath \"$($i)\\InprocServer32\") -Name '(default)' -ErrorAction SilentlyContinue).'(default)';\n                                    ) | Where-Object { $null -ne $_ } | Sort-Object -Unique\n                                    Category = 'Explorer'\n                                }\n                            } else {\n                                Get-RegValue -Path \"$key\\$($_)\" -Name 'CLSID' @Category\n                            }\n                        }\n                    }\n                }\n\n                # SharedTaskScheduler\n                $null,'Wow6432Node' | Foreach-Object -Process {\n                    Get-RegValue -Path \"HKLM:\\SOFTWARE\\$($_)\\Microsoft\\Windows\\CurrentVersion\\Explorer\\SharedTaskScheduler\" -Name '*' @Category\n                }\n\n                # ShellServiceObjects\n                $null,'Wow6432Node' | Foreach-Object -Process {\n                    $ClassesPath =  \"HKLM:\\SOFTWARE\\$($_)\\Classes\\CLSID\"\n                    $key = \"HKLM:\\SOFTWARE\\$($_)\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ShellServiceObjects\"\n                    (Get-Item -Path $key).GetSubKeyNames() | ForEach-Object -Process {\n                        @{\n                            Path = $key\n                            Item = $_\n                            Value = $(\n                                try {\n                                    (Get-ItemProperty -Path (Join-Path -Path $ClassesPath -ChildPath \"$($_)\\InprocServer32\") -Name '(default)' -ErrorAction Stop).'(default)'\n                                } catch {\n                                    $null\n                                }\n                            )\n                            Category = 'Explorer'\n                        }\n                    }\n                }\n\n                # ShellExecuteHooks\n                $null,'Wow6432Node' | Foreach-Object -Process {\n                    $key = \"HKLM:\\SOFTWARE\\$($_)\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ShellExecuteHooks\"\n                    if (Test-Path -Path $key -PathType Container) {\n                        $ClassesPath =  \"HKLM:\\SOFTWARE\\$($_)\\Classes\\CLSID\"\n                         (Get-Item -Path $key).GetValueNames() | ForEach-Object {\n                            # Get-RegValue -Path $key -Name $_ @Category\n                            @{\n                                Path = $key\n                                Item = $_\n                                Value = (Get-ItemProperty -Path (Join-Path -Path $ClassesPath -ChildPath \"$($_)\\InprocServer32\") -Name '(default)').'(default)'\n                                Category = 'Explorer'\n                            }\n                         }\n                    }\n                }\n    \n                # ShellServiceObjectDelayLoad\n                $null,'Wow6432Node' | Foreach-Object -Process {\n                    Get-RegValue -Path \"HKLM:\\SOFTWARE\\$($_)\\Microsoft\\Windows\\CurrentVersion\\ShellServiceObjectDelayLoad\" -Name '*' @Category\n                }\n\n                # Handlers\n                @(\n                    @{Name = '*' ; Properties = @('ContextMenuHandlers','PropertySheetHandlers')},\n                    @{Name ='Drive'  ; Properties = @('ContextMenuHandlers')},\n                    @{Name ='AllFileSystemObjects'  ; Properties = @('ContextMenuHandlers','DragDropHandlers','PropertySheetHandlers')},\n                    @{Name ='Directory'  ; Properties = @('ContextMenuHandlers','DragDropHandlers','PropertySheetHandlers', 'CopyHookHandlers')},\n                    @{Name ='Directory\\Background'  ; Properties = @('ContextMenuHandlers')},\n                    @{Name ='Folder' ; Properties = @('ColumnHandlers','ContextMenuHandlers','DragDropHandlers','ExtShellFolderViews','PropertySheetHandlers')}\n                ) | ForEach-Object -Process {\n        \n                    $Name = $_.Name\n                    $Properties = $_.Properties\n\n                    $null,'Wow6432Node' | Foreach-Object -Process { \n                        $key = \"HKLM:\\Software\\$($_)\\Classes\\$Name\\ShellEx\"\n                        $ClassPath = \"HKLM:\\Software\\$($_)\\Classes\\CLSID\"\n                        $Hive = $_\n                        $Properties | ForEach-Object -Process {\n                            $subkey = Join-Path -Path $key -ChildPath $_\n                            try {\n                                (Get-Item -LiteralPath $subkey -ErrorAction SilentlyContinue).GetSubKeyNames() | ForEach-Object -Process {\n                                    if ($(try {\n                                        [system.guid]::Parse($_) | Out-Null\n                                        $true\n                                    } catch {\n                                        $false\n                                    })) {\n                                        if (Test-Path -Path (Join-Path -Path $ClassPath -ChildPath \"$($_)\\InprocServer32\") -PathType Container) {\n                                            # don't change anything\n                                        } else {\n                                            if ($Hive) {\n                                                $ClassPath = 'HKLM:\\Software\\Classes\\CLSID'\n                                            } else {\n                                                $ClassPath = 'HKLM:\\Software\\Wow6432Node\\Classes\\CLSID'\n                                            }\n                                        }\n                                        if (Test-PAth -Path (Join-Path -Path $ClassPath -ChildPath \"$($_)\\InprocServer32\") -PathType Container) {\n                                            @{\n                                                Path = $key\n                                                Item = $_\n                                                Value = (Get-ItemProperty -Path (Join-Path -Path $ClassPath -ChildPath \"$($_)\\InprocServer32\") -Name '(default)' -ErrorAction SilentlyContinue).'(default)'\n                                                Category = 'Explorer'\n                                            }\n                                        }\n                                    } else {\n                                        Get-RegValue -Path \"$subkey\\$($_)\" -Name '*' @Category\n                                    }\n                                }\n                             } catch {\n                             }\n                        }\n                    }\n                } \n\n                # ShellIconOverlayIdentifiers\n                $null,'Wow6432Node' | Foreach-Object -Process {\n                    $key = \"HKLM:\\SOFTWARE\\$($_)\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ShellIconOverlayIdentifiers\"\n                    if (Test-Path -Path $key -PathType Container) {\n                        (Get-Item -Path $key).GetSubKeyNames() | ForEach-Object -Process {\n                            Get-RegValue -Path \"$key\\$($_)\" -Name '*' @Category\n                        }\n                    }\n                }\n\n                # LangBarAddin\n                Get-RegValue -Path 'HKLM:\\Software\\Microsoft\\Ctf\\LangBarAddin' -Name '*' @Category\n\n                #endregion Explorer\n\n                #region User Explorer\n\n                # Filter & Handler\n                'Filter','Handler' | ForEach-Object -Process {\n                    $key = \"HKCU:\\SOFTWARE\\Classes\\Protocols\\$($_)\"\n                    if (Test-Path -Path $key  -PathType Container) {\n                        (Get-Item -Path $key).GetSubKeyNames() | ForEach-Object -Process {\n                                Get-RegValue -Path \"$key\\$($_)\" -Name 'CLSID' @Category\n                        }\n                    }\n                }   \n\n                if (Test-Path -Path 'HKCU:\\SOFTWARE\\Microsoft\\Internet Explorer\\Desktop\\Components' -PathType Container) {\n                    $key = 'HKCU:\\SOFTWARE\\Microsoft\\Internet Explorer\\Desktop\\Components'\n\t                (Get-Item -Path $key).GetSubKeyNames() | ForEach-Object -Process {\n\t\t\t                Get-RegValue -Path \"$key\\$($_)\" -Name 'Source' @Category\n\t                }\n                }\n\n                # ShellServiceObjects\n                if (Test-Path -Path 'HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ShellServiceObjects' -PathType Container) {\n                    $ClassesPath =  \"HKCU:\\SOFTWARE\\$($_)\\Classes\\CLSID\"\n                    $key = 'HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ShellServiceObjects'\n                    (Get-Item -Path $key).GetSubKeyNames() | ForEach-Object -Process {\n                        @{\n                            Path = $key\n                            Item = $_\n                            Value = (Get-ItemProperty -Path (Join-Path -Path $ClassesPath -ChildPath \"$($_)\\InprocServer32\") -Name '(default)').'(default)'\n                            Category = 'Explorer'\n                        }\n                    }\n                }\n    \n                # ShellServiceObjectDelayLoad\n                Get-RegValue -Path 'HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\ShellServiceObjectDelayLoad' -Name '*' @Category\n\n                # Handlers\n                @(\n                    @{Name = '*' ; Properties = @('ContextMenuHandlers','PropertySheetHandlers')},\n                    @{Name ='Drive'  ; Properties = @('ContextMenuHandlers')},\n                    @{Name ='AllFileSystemObjects'  ; Properties = @('ContextMenuHandlers','DragDropHandlers','PropertySheetHandlers')},\n                    @{Name ='Directory'  ; Properties = @('ContextMenuHandlers','DragDropHandlers','PropertySheetHandlers', 'CopyHookHandlers')},\n                    @{Name ='Directory\\Background'  ; Properties = @('ContextMenuHandlers')},\n                    @{Name ='Folder' ; Properties = @('ColumnHandlers','ContextMenuHandlers','DragDropHandlers','ExtShellFolderViews','PropertySheetHandlers')}\n                ) | ForEach-Object -Process {\n        \n                    $Name = $_.Name\n                    $Properties = $_.Properties\n\n                    $key = \"HKCU:\\Software\\Classes\\$Name\\ShellEx\"\n                    $Properties | ForEach-Object -Process {\n                        $subkey = Join-Path -Path $key -ChildPath $_\n                        try {\n                            (Get-Item -LiteralPath $subkey -ErrorAction SilentlyContinue).GetSubKeyNames() | ForEach-Object -Process {\n                                Get-RegValue -Path \"$subkey\\$($_)\" -Name '*' @Category\n                            }\n                        } catch {\n                        }\n                    }\n                }\n\n                # ShellIconOverlayIdentifiers\n                $key = 'HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ShellIconOverlayIdentifiers'\n                if (Test-Path -Path $key -PathType Container) {\n                    (Get-Item -Path $key).GetSubKeyNames() | ForEach-Object -Process {\n                        Get-RegValue -Path \"$key\\$($_)\" -Name '*' @Category\n                    }\n                }\n\n                # LangBarAddin\n                Get-RegValue -Path 'HKCU:\\Software\\Microsoft\\Ctf\\LangBarAddin' -Name '*' @Category\n\n                # NEW! POWELIKS use of Window's thumbnail cache\n                if (Test-Path -Path 'HKCU:\\Software\\Classes\\Clsid\\{AB8902B4-09CA-4bb6-B78D-A8F59079A8D5}') {\n                    Write-Warning -Message 'Infected by PoweLiks malware'\n                    # Step1: restore read access\n                    try {\n                        $ParentACL = Get-Acl -Path 'HKCU:\\Software\\Classes\\Clsid'\n                        $k = [Microsoft.Win32.Registry]::CurrentUser.OpenSubKey('Software\\Classes\\Clsid\\{AB8902B4-09CA-4bb6-B78D-A8F59079A8D5}','ReadWriteSubTree','TakeOwnership')\n                        $acl  = $k.GetAccessControl()\n                        $acl.SetAccessRuleProtection($false,$true)\n                        $rule = New-Object System.Security.AccessControl.RegistryAccessRule ($ParentACL.Owner,'FullControl','Allow')\n                        $acl.SetAccessRule($rule)\n                        $k.SetAccessControl($acl)\n                        Write-Verbose -Message \"Successuflly restored read access for $($ParentACL.Owner) on registry key\"\n                    } catch {\n                        Write-Warning -Message \"Failed to restore read access for $($ParentACL.Owner) on registry key\"\n                    }\n                    # Step2: read the content of subkeys\n                    'Inprocserver32','localserver32' | ForEach-Object {\n                        try {\n                            (Get-ItemProperty -Path \"HKCU:\\Software\\Classes\\Clsid\\{AB8902B4-09CA-4bb6-B78D-A8F59079A8D5}\\$($_)\" -Name '(default)' -ErrorAction Stop).'(default)'\n                        } catch {\n                        }\n                    }\n                }\n                #endregion User Explorer\n            }\n            if ($All -or $SidebarGadgets) {\n                Write-Verbose -Message 'Looking for Sidebar gadgets'\n                #region User Sidebar gadgets\n\n                if (Test-Path (Join-Path -Path (Split-Path -Path $($env:AppData) -Parent) -ChildPath 'Local\\Microsoft\\Windows Sidebar\\Settings.ini')) {\n\n                    Get-Content -Path (\n                        Join-Path -Path (Split-Path -Path $($env:AppData) -Parent) -ChildPath 'Local\\Microsoft\\Windows Sidebar\\Settings.ini'\n                    ) | \n                    Select-String -Pattern '^PrivateSetting_GadgetName=' | ForEach-Object {\n\n                            @{\n                                Path = Join-Path -Path (Split-Path -Path $($env:AppData) -Parent) -ChildPath 'Local\\Microsoft\\Windows Sidebar\\Settings.ini'\n                                Item = [string]::Empty\n                                Value = ($_.Line -split '=' | Select-Object -Last 1) -replace '%5C','\\' -replace '%20',' '\n                                Category = 'SideBar Gadgets'\n                            }\n                     }\n                }\n                #endregion User Sidebar gadgets\n            }\n            if ($All -or $ImageHijacks) {\n                Write-Verbose -Message 'Looking for Image hijacks'\n                #region Image Hijacks\n\t            $Category = @{ Category = 'Image Hijacks'}\n                $null,'Wow6432Node' | Foreach-Object {\n\t\t            $key = \"HKLM:\\Software\\$($_)\\Microsoft\\Windows NT\\CurrentVersion\\Image File Execution Options\"\n\t\t            (Get-Item -Path $key).GetSubKeyNames() | ForEach-Object -Process {\n\t\t\t            Get-RegValue -Path \"$key\\$($_)\" -Name 'Debugger' @Category\n\t\t            }\n\t            }\t\t\n\n                # Autorun macro\t\n\t            $null,'Wow6432Node' | Foreach-Object {\n\t\t            Get-RegValue -Path \"HKLM:\\Software\\$($_)\\Microsoft\\Command Processor\" -Name 'Autorun' @Category\t\t\n\t            }\n\t\n                # Exefile\n                @{\n                    Path = 'HKLM:\\SOFTWARE\\Classes\\Exefile\\Shell\\Open\\Command'\n                    Item = 'exefile'\n                    Value = (Get-ItemProperty -Path 'HKLM:\\SOFTWARE\\Classes\\Exefile\\Shell\\Open\\Command' -Name '(default)').'(default)'\n                    Category = 'Image Hijacks'\n                }\n\t\n\t            '.exe','.cmd' | Foreach-Object {\n\t\t            $assoc = (Get-ItemProperty -Path \"HKLM:\\Software\\Classes\\$($_)\" -Name '(default)').'(default)'\n                    @{\n                        Path = \"HKLM:\\Software\\Classes\\$assoc\\shell\\open\\command\"\n                        Item = $_ \n                        Value = (Get-ItemProperty -Path \"HKLM:\\SOFTWARE\\Classes\\$assoc\\Shell\\Open\\Command\" -Name '(default)').'(default)'\n                        Category = 'Image Hijacks'\n                    }\n\t            }\n\n                # Htmlfile\n                @{\n                    Path = 'HKLM:\\SOFTWARE\\Classes\\htmlfile\\shell\\open\\command'\n                    Item = 'htmlfile'\n                    Value = (Get-ItemProperty -Path 'HKLM:\\SOFTWARE\\Classes\\htmlfile\\shell\\open\\command' -Name '(default)').'(default)'\n                    Category = 'Image Hijacks'\n                }\n                #endregion Image Hijacks\n\n                #region User Image Hijacks\n\n                Get-RegValue -Path 'HKCU:\\Software\\Microsoft\\Command Processor' -Name 'Autorun' @Category\t\t\n\t\n                # Exefile\n                if (Test-Path -Path 'HKCU:\\SOFTWARE\\Classes\\Exefile\\Shell\\Open\\Command') {\n                    @{\n                        Path = 'HKCU:\\SOFTWARE\\Classes\\Exefile\\Shell\\Open\\Command'\n                        Item = 'exefile'\n                        Value = (Get-ItemProperty -Path 'HKCU:\\SOFTWARE\\Classes\\Exefile\\Shell\\Open\\Command' -Name '(default)').'(default)'\n                        Category = 'Image Hijacks'\n                    }\n                }\n\t\n\t            '.exe','.cmd' | Foreach-Object {\n                    if (Test-Path -Path \"HKCU:\\Software\\Classes\\$($_)\") {\n\t\t                $assoc = (Get-ItemProperty -Path \"HKCU:\\Software\\Classes\\$($_)\" -Name '(default)'-ErrorAction SilentlyContinue).'(default)'\n                        if ($assoc) {\n                            @{\n                                Path = \"HKCU:\\Software\\Classes\\$assoc\\shell\\open\\command\"\n                                Item = $_ \n                                Value = (Get-ItemProperty -Path \"HKCU:\\SOFTWARE\\Classes\\$assoc\\Shell\\Open\\Command\" -Name '(default)' -ErrorAction SilentlyContinue).'(default)'\n                                Category = 'Image Hijacks'\n                            }\n                        }\n                    }\n\t            }\n\n                # Htmlfile\n                if (Test-Path -Path 'HKCU:\\SOFTWARE\\Classes\\htmlfile\\shell\\open\\command') {\n                    @{\n                        Path = 'HKCU:\\SOFTWARE\\Classes\\htmlfile\\shell\\open\\command'\n                        Item = 'htmlfile'\n                        Value = (Get-ItemProperty -Path 'HKCU:\\SOFTWARE\\Classes\\htmlfile\\shell\\open\\command' -Name '(default)').'(default)'\n                        Category = 'Image Hijacks'\n                    }\n                }\n                #endregion User Image Hijacks\n            }\n            if ($All -or $InternetExplorerAddons) {\n                Write-Verbose -Message 'Looking for Internet Explorer Add-ons entries'\n                #region Internet Explorer\n\n                $Category = @{ Category = 'Internet Explorer'}\n    \n                # Browser Helper Objects\n                $null,'Wow6432Node' | Foreach-Object {\n                    $ClassesPath =  \"HKLM:\\SOFTWARE\\$($_)\\Classes\\CLSID\"\n                    $key = \"HKLM:\\SOFTWARE\\$($_)\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Browser Helper Objects\"\n                    if (Test-Path -Path $key -PathType Container) {\n                        (Get-Item -Path $key).GetSubKeyNames() | ForEach-Object -Process {\n                            @{\n                                Path = $key\n                                Item = $_\n                                Value = (Get-ItemProperty -Path (Join-Path -Path $ClassesPath -ChildPath \"$($_)\\InprocServer32\") -Name '(default)').'(default)'\n                                Category = 'Internet Explorer'\n                            }\n                        }\n                    }\n                }\n\n                # IE Toolbars\n                $null,'Wow6432Node' | Foreach-Object -Process {\n                    Get-RegValue -Path \"HKLM:\\SOFTWARE\\$($_)\\Microsoft\\Internet Explorer\\Toolbar\" -Name '*' @Category\n                }\n\n                # Explorer Bars\n                $null,'Wow6432Node' | Foreach-Object -Process {\n                    $ClassesPath =  \"HKLM:\\SOFTWARE\\$($_)\\Classes\\CLSID\"\n                    $key = \"HKLM:\\SOFTWARE\\$($_)\\Microsoft\\Internet Explorer\\Explorer Bars\"\n                    try {\n                        (Get-Item -Path $key -ErrorAction Stop).GetSubKeyNames() | ForEach-Object -Process {\n                            @{\n                                Path = $key\n                                Item = $_\n                                Value = (Get-ItemProperty -Path (Join-Path -Path $ClassesPath -ChildPath \"$($_)\\InprocServer32\") -Name '(default)').'(default)'\n                                Category = 'Internet Explorer'\n                            }\n                        }\n                    } catch {\n                    }\n                }\n\n                # IE Extensions\n                $null,'Wow6432Node' | Foreach-Object {\n                    $key = \"HKLM:\\SOFTWARE\\$($_)\\Microsoft\\Internet Explorer\\Extensions\"\n                    if (Test-Path -Path $key -PathType Container) {\n                        (Get-Item -Path $key -ErrorAction SilentlyContinue).GetSubKeyNames() | ForEach-Object -Process {\n                            Get-RegValue -Path \"$key\\$($_)\" -Name 'ClsidExtension' @Category\n                        }\n                    }\n                }\n\n                #endregion Internet Explorer\n\n                #region User Internet Explorer\n\n                # UrlSearchHooks\n                $ClassesPath =  'HKLM:\\SOFTWARE\\Classes\\CLSID'\n                $key = 'HKCU:\\Software\\Microsoft\\Internet Explorer\\UrlSearchHooks'\n                if (Test-Path -Path $key -PathType Container) {\n                    (Get-Item -Path $key).GetValueNames() | ForEach-Object -Process {\n                        @{\n                            Path = $key\n                            Item = $_\n                            Value = (Get-ItemProperty -Path (Join-Path -Path $ClassesPath -ChildPath \"$($_)\\InprocServer32\") -Name '(default)').'(default)'\n                            Category = 'Internet Explorer'\n                        }\n                    }\n                }\n\n                # Explorer Bars\n                $null,'Wow6432Node' | Foreach-Object -Process {\n                    $ClassesPath =  \"HKLM:\\SOFTWARE\\$($_)\\Classes\\CLSID\"\n                    $key = \"HKCU:\\SOFTWARE\\$($_)\\Microsoft\\Internet Explorer\\Explorer Bars\"\n                    if (Test-Path -Path $key -PathType Container) {\n                        (Get-Item -Path $key).GetSubKeyNames() | ForEach-Object -Process {\n                            @{\n                                Path = $key\n                                Item = $_\n                                Value = (Get-ItemProperty -Path (Join-Path -Path $ClassesPath -ChildPath \"$($_)\\InprocServer32\") -Name '(default)').'(default)'\n                                Category = 'Internet Explorer'\n                            }\n                        }\n                    }\n                }\n\n                # IE Extensions\n                $null,'Wow6432Node' | Foreach-Object {\n                    $key = \"HKCU:\\SOFTWARE\\$($_)\\Microsoft\\Internet Explorer\\Extensions\"\n                    if (Test-Path -Path $key -PathType Container) {\n                        (Get-Item -Path $key -ErrorAction SilentlyContinue).GetSubKeyNames() | ForEach-Object -Process {\n                            Get-RegValue -Path \"$key\\$($_)\" -Name 'ClsidExtension' @Category\n                        }\n                    }\n                }\n\n                #endregion User Internet Explorer\n            }\n            if ($All -or $KnownDLLs) {\n                Write-Verbose -Message 'Looking for Known DLLs entries'\n                #region Known Dlls\n\t            Get-RegValue -Path 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Session Manager\\KnownDLLs' -Name '*' -Category 'Known Dlls'\n                #endregion Known Dlls\n            }\n            if ($All -or $Logon) {\n                Write-Verbose -Message 'Looking for Logon Startup entries'\n                #region Logon\n\n                $Category = @{ Category = 'Logon'}\n\n                # Winlogon\n                Get-RegValue -Path 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon' -Name 'VmApplet','Userinit','Shell','TaskMan','AppSetup' @Category\n\n                # GPExtensions\n\t            $key = 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\GPExtensions'\n                if (Test-Path -Path $key -PathType Container) {\n\t\t            (Get-Item -Path $key).GetSubKeyNames() | ForEach-Object -Process {\n                        try {\n                            @{\n                                Path = $key\n                                Item = $_\n                                Value = (Get-ItemProperty -Path (Join-Path -Path $key -ChildPath $_) -Name 'DllName' -ErrorAction Stop).'DllName'\n                                Category = 'Logon'\n                            }\n                        } catch {}\t\t\t\n\t\t            }\t\t\t\n\t            }\n    \n                # Domain Group Policies scripts\n                'Startup','Shutdown','Logon','Logoff' | ForEach-Object -Process {\n                    $key = \"HKLM:\\Software\\Policies\\Microsoft\\Windows\\System\\Scripts\\$($_)\"\n                    if (Test-Path -Path $key) {\n                        (Get-Item -Path $key).GetSubKeyNames() | ForEach-Object -Process {\n                            $subkey = (Join-Path -Path $key -ChildPath $_)\n                            (Get-Item -Path $subkey).GetSubKeyNames() | ForEach-Object -Process {\n                                Get-RegValue -Path (Join-Path -Path $subkey -ChildPath $_) -Name 'script' @Category \n                            }\n                        }\n                    }\n                }    \n\n                # Local GPO scripts\n                'Startup','Shutdown' | ForEach-Object -Process {\n                    $key = \"HKLM:\\Software\\Microsoft\\Windows\\CurrentVersion\\Group Policy\\Scripts\\$($_)\"\n                    if (Test-Path -Path $key) {\n                        (Get-Item -Path $key).GetSubKeyNames() | ForEach-Object -Process {\n                            $subkey = (Join-Path -Path $key -ChildPath $_)\n                            (Get-Item -Path $subkey).GetSubKeyNames() | ForEach-Object -Process {\n                                Get-RegValue -Path (Join-Path -Path $subkey -ChildPath $_) -Name 'script' @Category \n                            }\n                        }\n                    }\n                }    \n\n                # Shell override by GPO\n                Get-RegValue -Path 'HKLM:\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System' -Name 'Shell' @Category\n\n                # AlternateShell\n                Get-RegValue -Path 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\SafeBoot' -Name 'AlternateShell' @Category\n\n                # AvailableShells\n                Get-RegValue -Path 'HKLM:\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\AlternateShells' -Name 'AvailableShells' @Category\n\n                # Terminal server\n                Get-RegValue -Path 'HKLM:\\System\\CurrentControlSet\\Control\\Terminal Server\\Wds\\rdpwd' -Name 'StartupPrograms' @Category\n                Get-RegValue -Path 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Terminal Server\\Install\\Software\\Microsoft\\Windows\\CurrentVersion\\Runonce' -Name '*' @Category\n                Get-RegValue -Path 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Terminal Server\\Install\\Software\\Microsoft\\Windows\\CurrentVersion\\RunonceEx' -Name '*' @Category\n                Get-RegValue -Path 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Terminal Server\\Install\\Software\\Microsoft\\Windows\\CurrentVersion\\Run' -Name '*' @Category\n                Get-RegValue -Path 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\WinStations\\RDP-Tcp'  -Name 'InitialProgram' @Category\n\n                # Run\n                $null,'Wow6432Node' | Foreach-Object { Get-RegValue -Path \"HKLM:\\SOFTWARE\\$($_)\\Microsoft\\Windows\\CurrentVersion\\Run\" -Name '*' @Category }\n\n                # RunOnce\n                $null,'Wow6432Node' | Foreach-Object { Get-RegValue -Path \"HKLM:\\SOFTWARE\\$($_)\\Microsoft\\Windows\\CurrentVersion\\RunOnce\" -Name '*' @Category }\n\n                # RunOnceEx\n                $null,'Wow6432Node' | Foreach-Object { Get-RegValue -Path \"HKLM:\\SOFTWARE\\$($_)\\Microsoft\\Windows\\CurrentVersion\\RunOnceEx\" -Name '*' @Category }\n\n                # LNK files or direct executable\n                if (Test-Path -Path \"$($env:systemdrive)\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\" -PathType Container) {\n                    $Wsh = new-object -comobject 'WScript.Shell'\n                    Get-ChildItem -Path \"$($env:systemdrive)\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\" |ForEach-Object {\n                        $File = $_\n                        $header = (Get-Content -Path $($_.FullName) -Encoding Byte -ReadCount 1 -TotalCount 2) -as [string]\n                        Switch ($header) {\n                            '77 90' {\n                                @{\n                                    Path = \"$($env:systemdrive)\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\"\n                                    Item = $File.Name\n                                    Value = $File.FullName\n                                    Category = 'Logon'\n                                }\n                                break\n                            }\n                            '76 0' {\n                                $shortcut = $Wsh.CreateShortcut($File.FullName)\n                                @{\n                                    Path = \"$($env:systemdrive)\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\"\n                                    Item = $File.Name\n                                    Value = \"$($shortcut.TargetPath) $($shortcut.Arguments)\"\n                                    Category = 'Logon'\n                                }\n                                break\n\n                            }\n                            default {}\n                        }\n                    }\n                }\n\n                # Run by GPO\n                Get-RegValue -Path 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer\\Run' -Name '*' @Category\n\n                # Show all subkey that have a StubPath value\n                $null,'Wow6432Node' | Foreach-Object { \n                    $key = \"HKLM:\\SOFTWARE\\$($_)\\Microsoft\\Active Setup\\Installed Components\"\n                    (Get-Item -Path $key).GetSubKeyNames() | ForEach-Object -Process {\n                        Get-RegValue -Path \"$key\\$($_)\" -Name 'StubPath' @Category\n                    }\n\n                }\n\n                Get-RegValue -Path 'HKLM:\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows' -Name 'IconServiceLib' @Category\n\n                $null,'Wow6432Node' | Foreach-Object { Get-RegValue -Path \"HKLM:\\SOFTWARE\\$($_)\\Microsoft\\Windows CE Services\\AutoStartOnConnect\" -Name '*' @Category }\n                $null,'Wow6432Node' | Foreach-Object { Get-RegValue -Path \"HKLM:\\SOFTWARE\\$($_)\\Microsoft\\Windows CE Services\\AutoStartOnDisconnect\" -Name '*' @Category }\n\n                #endregion Logon\n\n                #region User Logon\n\n                # Local GPO scripts\n                'Logon','Logoff' | ForEach-Object -Process {\n                    $key = \"HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Group Policy\\Scripts\\$($_)\"\n                    if (Test-Path -Path $key) {\n                        (Get-Item -Path $key).GetSubKeyNames() | ForEach-Object -Process {\n                            $subkey = (Join-Path -Path $key -ChildPath $_)\n                            (Get-Item -Path $subkey).GetSubKeyNames() | ForEach-Object -Process {\n                                # (Join-Path -Path $subkey -ChildPath $_)\n                                Get-RegValue -Path (Join-Path -Path $subkey -ChildPath $_) -Name 'script' @Category \n                            }\n\n                        }\n                    }\n                }\n\n                # Shell override by GPO\n                Get-RegValue -Path 'HKCU:\\Software\\Microsoft\\Windows\\CurrentVersion\\Policies\\System' -Name 'Shell' @Category\n\n                # LNK files or direct executable\n                if (Test-Path -Path \"$($env:AppData)\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\") {\n                    $Wsh = new-object -comobject 'WScript.Shell'\n                    Get-ChildItem -Path \"$($env:AppData)\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\" |ForEach-Object {\n                        $File = $_\n                        $header = (Get-Content -Path $($_.FullName) -Encoding Byte -ReadCount 1 -TotalCount 2) -as [string]\n                        Switch ($header) {\n                            '77 90' {\n                                @{\n                                    Path = \"$($env:AppData)\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\"\n                                    Item = $File.Name\n                                    Value = $File.FullName\n                                    Category = 'Logon'\n                                }\n                                break\n                            }\n                            '76 0' {\n                                $shortcut = $Wsh.CreateShortcut($File.FullName)\n                                @{\n                                    Path = \"$($env:AppData)\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\"\n                                    Item = $File.Name\n                                    Value = \"$($shortcut.TargetPath) $($shortcut.Arguments)\"\n                                    Category = 'Logon'\n                                }\n                                break\n\n                            }\n                            default {}\n                        }\n                    }\n                }\n    \n                Get-RegValue -Path 'HKCU:\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows' -Name 'Load' @Category\n                Get-RegValue -Path 'HKCU:\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Windows' -Name 'Run' @Category\n\n                # Run by GPO\n                Get-RegValue -Path 'HKCU:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Policies\\Explorer\\Run' -Name '*' @Category\n    \n                # Run\n                $null,'Wow6432Node' | ForEach-Object {\n                    Get-RegValue -Path \"HKCU:\\Software\\$($_)\\Microsoft\\Windows\\CurrentVersion\\Run\" -Name '*' @Category \n                }\n\n                # RunOnce\n                $null,'Wow6432Node' | ForEach-Object {\n                    Get-RegValue -Path \"HKCU:\\Software\\$($_)\\Microsoft\\Windows\\CurrentVersion\\RunOnce\" -Name '*' @Category \n                }\n\n                # RunOnceEx\n                $null,'Wow6432Node' | ForEach-Object {\n                    Get-RegValue -Path \"HKCU:\\Software\\$($_)\\Microsoft\\Windows\\CurrentVersion\\RunOnceEx\" -Name '*' @Category \n                }\n\n                Get-RegValue -Path 'HKCU:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Terminal Server\\Install\\Software\\Microsoft\\Windows\\CurrentVersion\\Runonce' -Name '*' @Category\n                Get-RegValue -Path 'HKCU:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Terminal Server\\Install\\Software\\Microsoft\\Windows\\CurrentVersion\\RunonceEx' -Name '*' @Category\n                Get-RegValue -Path 'HKCU:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Terminal Server\\Install\\Software\\Microsoft\\Windows\\CurrentVersion\\Run' -Name '*' @Category\n\n                #endregion User Logon\n\n            }\n            if ($All -or $Winsock) {\n                Write-Verbose -Message 'Looking for Winsock protocol and network providers entries'\n                #region Winsock providers\n\n                $Category = @{ Category = 'Winsock Providers'}\n\n                $null,'64' | ForEach-Object -Process {\n                    $key = \"HKLM:\\System\\CurrentControlSet\\Services\\WinSock2\\Parameters\\Protocol_Catalog9\\Catalog_Entries$($_)\"\n                    (Get-Item -Path $key).GetSubKeyNames() | ForEach-Object -Process {\n                        @{\n                            Path = \"$key\\$($_)\"\n                            Item = 'PackedCatalogItem'\n                            Value = ((New-Object -TypeName System.Text.ASCIIEncoding).GetString(\n                                (Get-ItemProperty -Path \"$key\\$($_)\" -Name PackedCatalogItem).PackedCatalogItem,0,211\n                            ) -split ([char][int]0))[0]\n                            Category = 'Winsock Providers'\n                        }\n                    }\n                }\n\n                $null,'64' | ForEach-Object -Process {\n                    $key = \"HKLM:\\System\\CurrentControlSet\\Services\\WinSock2\\Parameters\\NameSpace_Catalog5\\Catalog_Entries$($_)\"\n                    (Get-Item -Path $key).GetSubKeyNames() | ForEach-Object -Process {\n                        Get-RegValue -Path \"$key\\$($_)\" -Name 'LibraryPath' @Category\n                    }\n                }\n                #endregion Winsock providers\n\n                #region Network providers\n\t            $Category = @{ Category = 'Network Providers'}\n                $key = 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\NetworkProvider\\Order'\n\t            (Get-RegValue -Path $key -Name 'ProviderOrder' @Category).Value -split ',' | ForEach-Object {\n\t\t            Get-RegValue -Path \"HKLM:\\SYSTEM\\CurrentControlSet\\services\\$($_)\\NetworkProvider\" -Name 'ProviderPath' @Category\n\t            }\n                #endregion Network providers\n            }\n            if ($All -or $Codecs) {\n                Write-Verbose -Message 'Looking for Codecs'\n                #region Codecs\n\t            $Category = @{ Category = 'Codecs'}\n\n                # Drivers32\n\t            $null,'Wow6432Node' | Foreach-Object {\n\t\t            Get-RegValue -Path \"HKLM:\\Software\\$($_)\\Microsoft\\Windows NT\\CurrentVersion\\Drivers32\" -Name '*' @Category\n\t            }\t\t\n\n                # Filter\n\t            $key = 'HKLM:\\Software\\Classes\\Filter'\n                if (Test-Path -Path $key -PathType Container) {\n\t\t            (Get-Item -Path $key).GetSubKeyNames() | ForEach-Object -Process {\n                        @{\n                            Path = $key\n                            Item = $_\n                            Value = (Get-ItemProperty -Path (Join-Path -Path 'HKLM:\\SOFTWARE\\Classes\\CLSID' -ChildPath \"$($_)\\InprocServer32\") -Name '(default)' -ErrorAction SilentlyContinue).'(default)'\n                            Category = 'Codecs'\n                        }\t\t\t\n\t\t            }\t\t\t\n\t            }\n\n                # Instances\n\t            @('{083863F1-70DE-11d0-BD40-00A0C911CE86}','{AC757296-3522-4E11-9862-C17BE5A1767E}',\n\t            '{7ED96837-96F0-4812-B211-F13C24117ED3}','{ABE3B9A4-257D-4B97-BD1A-294AF496222E}') | Foreach-Object -Process {\n\t\t            $Item = $_\n\t\t            $null,'Wow6432Node' | Foreach-Object {\n\t\t\t            $key = \"HKLM:\\Software\\$($_)\\Classes\\CLSID\\$Item\\Instance\"\n                        $clsidp = \"HKLM:\\Software\\$($_)\\Classes\\CLSID\"\n                        if (Test-Path -Path $key -PathType Container) {\n\t\t\t                (Get-Item -Path $key).GetSubKeyNames() | ForEach-Object -Process {\n                                try {\n\t                                @{\n\t                                    Path = $key\n\t                                    Item = $_\n                                        Value = (Get-ItemProperty -Path (Join-Path -Path $clsidp -ChildPath \"$($_)\\InprocServer32\") -Name '(default)' -ErrorAction Stop).'(default)'\n\t                                    Category = 'Codecs'\n\t                                }\n                                } catch {\n                                }\t\t\n\t\t\t                }\n                        }\t\t\n\t\t            }\t\t\t\n\t            }\n                #endregion Codecs\n\n                #region User Codecs\n\n                # Drivers32\n\t            $null,'Wow6432Node' | Foreach-Object {\n\t\t            Get-RegValue -Path \"HKCU:\\Software\\$($_)\\Microsoft\\Windows NT\\CurrentVersion\\Drivers32\" -Name '*' @Category\n\t            }\t\t\n\n                # Filter\n\t            $key = 'HKCU:\\Software\\Classes\\Filter'\n                if (Test-Path -Path $key -PathType Container) {\n\t\t            (Get-Item -Path $key).GetSubKeyNames() | ForEach-Object -Process {\n                        @{\n                            Path = $key\n                            Item = $_\n                            Value = (Get-ItemProperty -Path (Join-Path -Path 'HKCU:\\SOFTWARE\\Classes\\CLSID' -ChildPath \"$($_)\\InprocServer32\") -Name '(default)' -ErrorAction SilentlyContinue).'(default)'\n                            Category = 'Codecs'\n                        }\t\t\t\n\t\t            }\t\t\t\n\t            }\n\n                # Instances\n\t            @('{083863F1-70DE-11d0-BD40-00A0C911CE86}','{AC757296-3522-4E11-9862-C17BE5A1767E}',\n\t            '{7ED96837-96F0-4812-B211-F13C24117ED3}','{ABE3B9A4-257D-4B97-BD1A-294AF496222E}') | Foreach-Object -Process {\n\t\t            $Item = $_\n\t\t            $null,'Wow6432Node' | Foreach-Object {\n\t\t\t            $key = \"HKCU:\\Software\\$($_)\\Classes\\CLSID\\$Item\\Instance\"\n                        if (Test-Path -Path $key -PathType Container) {\n\t\t\t                (Get-Item -Path $key).GetSubKeyNames() | ForEach-Object -Process {\n                                try {\n\t                                @{\n\t                                    Path = $key\n\t                                    Item = $_\n\t                                    Value = (Get-ItemProperty -Path (Join-Path -Path 'HKCU:\\SOFTWARE\\Classes\\CLSID' -ChildPath \"$($_)\\InprocServer32\") -Name '(default)' -ErrorAction Stop).'(default)'\n\t                                    Category = 'Codecs'\n\t                                }\n                                } catch {\n                                }\t\t\n\t\t\t                }\n                        }\t\t\n\t\t            }\t\t\t\n\t            }\n\n\n                #endregion User Codecs\n            }\n            if ($All -or $OfficeAddins) {\n                Write-Verbose -Message 'Looking for Office Addins entries'\n                #region Office Addins\n\n                <#\n                # FileName value or\n                # HKEY_LOCAL_MACHINE\\SOFTWARE\\Classes\\OneNote.OutlookAddin\\CLSID\n                #>\n                $Category = @{ Category = 'Office Addins'}\n                $null,'Wow6432Node' | Foreach-Object {\n                    $arc = $_\n                    'HKLM','HKCU' | ForEach-Object {\n                        $root = $_\n                        if (Test-Path \"$($root):\\SOFTWARE\\$($arc)\\Microsoft\\Office\") {\n                            (Get-Item \"$($root):\\SOFTWARE\\$($arc)\\Microsoft\\Office\").GetSubKeyNames() | ForEach-Object {\n                                if (Test-Path -Path (Join-Path -Path \"$($root):\\SOFTWARE\\$($arc)\\Microsoft\\Office\" -ChildPath \"$($_)\\Addins\") -PathType Container) {\n                                    $key = (Join-Path -Path \"$($root):\\SOFTWARE\\$($arc)\\Microsoft\\Office\" -ChildPath \"$($_)\\Addins\")\n                                    # Iterate through the Addins names\n                                    (Get-item -Path $key).GetSubKeyNames() | ForEach-Object {\n                                        try {\n\t                                        @{\n\t                                            Path = $key\n\t                                            Item = $_\n\t                                            Value = $(\n                                                    $clsid = (Get-ItemProperty -Path \"HKLM:\\SOFTWARE\\Classes\\$($_)\\CLSID\" -Name '(default)' -ErrorAction Stop).'(default)';\n                                                        if ((Get-ItemProperty -Path \"HKLM:\\SOFTWARE\\$arc\\Classes\\CLSID\\$clsid\\InprocServer32\"  -Name '(default)' -ErrorAction SilentlyContinue).'(default)') {\n                                                            (Get-ItemProperty -Path \"HKLM:\\SOFTWARE\\$arc\\Classes\\CLSID\\$clsid\\InprocServer32\"  -Name '(default)' -ErrorAction SilentlyContinue).'(default)'\n                                                        } else {\n                                                            $clsid\n                                                        }\n                                                        # (Get-ItemProperty -Path \"HKLM:\\SOFTWARE\\Classes\\CLSID\\$clsid\\InprocServer32\"  -Name '(default)' -ErrorAction SilentlyContinue).'(default)';\n                                                ) # | Where-Object { $null -ne $_ } | Sort-Object -Unique # | Select-Object -First 1\n                                                Category = 'Office Addins';\n\t                                        }\n                                        } catch {\n\n                                        }\n                                    }\n\n                                }\n                            }\n                        }\n                    } # hklm or hkcu\n                } \n                # Microsoft Office Memory Corruption Vulnerability (CVE-2015-1641)\n                'HKLM','HKCU' | ForEach-Object {\n                    $root = $_\n                    $key = \"$($root):\\SOFTWARE\\Microsoft\\Office test\\Special\\Perf\"\n                    if (Test-Path \"$($root):\\SOFTWARE\\Microsoft\\Office test\\Special\\Perf\") {\n                        if ((Get-ItemProperty -Path \"$($root):\\SOFTWARE\\Microsoft\\Office test\\Special\\Perf\" -Name '(default)' -ErrorAction SilentlyContinue).'(default)') {\n\t                        @{\n\t                            Path = $key\n\t                            Item = '(default)'\n                                Value = (Get-ItemProperty -Path \"$($root):\\SOFTWARE\\Microsoft\\Office test\\Special\\Perf\" -Name '(default)' -ErrorAction SilentlyContinue).'(default)'\n                                Category = 'Office Addins';\n\t                        }\n                        }\n                    }\n                }                \n                #endregion Office Addins\n            }\n            if ($All -or $PrintMonitorDLLs) {\n                Write-Verbose -Message 'Looking for Print Monitor DLLs entries'\n                #region Print monitors\n\t            $Category = @{ Category = 'Print Monitors'}\n\t            $key = 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Print\\Monitors'\n                (Get-Item -Path $key).GetSubKeyNames() | ForEach-Object -Process {\n\t\t            Get-RegValue -Path \"$key\\$($_)\" -Name 'Driver' @Category\n\t            }\n\n                Write-Verbose -Message 'Looking for Print Providers DLLs entries'\n                $key = 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Print\\Providers'\n                (Get-Item -Path $key).GetSubKeyNames() | ForEach-Object -Process {\n\t\t            Get-RegValue -Path \"$key\\$($_)\" -Name 'Name' @Category\n\t            }\n\n                #endregion Print monitors\n            }\n            if ($All -or $LSAsecurityProviders) {\n                Write-Verbose -Message 'Looking for LSA Security Providers entries'\n                #region LSA providers\n\t            $Category = @{ Category = 'LSA Providers'}\n\n                # REG_SZ \n\t            Get-RegValue -Path 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\SecurityProviders' -Name 'SecurityProviders' @Category\n\t\n                # REG_MULTI_SZ\n\t            'Authentication Packages','Notification Packages','Security Packages' | ForEach-Object {\n\t\t            $item = $_\n                    (Get-RegValue -Path 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Lsa' -Name $_ @Category).Value | ForEach-Object {\n                        if ($_ -ne '\"\"') {\n                            @{\n                                Path = 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Lsa'\n                                Item = $item\n                                Value = $_\n                                Category = 'LSA Providers'\n                            }\n                        }\n                    }\n\t            }\n\n                # HKLM\\SYSTEM\\CurrentControlSet\\Control\\Lsa\\OSConfig\\Security Packages\n                if (Test-Path -Path 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Lsa\\OSConfig' -PathType Container) {\n                    (Get-RegValue -Path 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Lsa\\OSConfig' -Name 'Security Packages'  @Category).Value | ForEach-Object {\n                        @{\n                            Path = 'HKLM:\\SYSTEM\\CurrentControlSet\\Control\\Lsa\\OSConfig'\n                            Item = 'Security Packages'\n                            Value = $_\n                            Category = 'LSA Providers'\n                        }\n                    }\n                }\n                #endregion LSA providers\n            }\n            if ($All -or $ServicesAndDrivers) {\n                Write-Verbose -Message 'Looking for Services and Drivers'\n                #region Services\n\n                (Get-Item -Path 'HKLM:\\System\\CurrentControlSet\\Services').GetSubKeyNames() | ForEach-Object {\n                    $Type = $null\n                    $key  = \"HKLM:\\System\\CurrentControlSet\\Services\\$($_)\"\n                    try {\n                        $Type = Get-ItemProperty -Path $key -Name Type -ErrorAction Stop\n                    } catch {\n                    }\n                    if ($Type) {\n                        Switch ($Type.Type) {\n                            1  {\n                                Get-RegValue -Path $key -Name 'ImagePath' -Category 'Drivers'\n                                break\n                            }\n                            16 {\n                                Get-RegValue -Path $key -Name 'ImagePath' -Category 'Services'\n                                Get-RegValue -Path \"$key\\Parameters\" -Name 'ServiceDll' -Category 'Services'\n                                break\n                            }\n                            32 {\n                                Get-RegValue -Path $key -Name 'ImagePath' -Category 'Services'\n                                Get-RegValue -Path \"$key\\Parameters\" -Name 'ServiceDll' -Category 'Services'\n                                break\n                            }\n                            default { \n                                # $_ \n                            }\n                        }\n                    }\n                }\n\n                # Font drivers\n                Get-RegValue -Path 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Font Drivers' -Name '*' -Category 'Services'\n\n                #endregion Services\n            }\n\n            if ($All -or $ScheduledTasks) {\n                Write-Verbose -Message 'Looking for Scheduled Tasks'\n\n                #region Scheduled Tasks\n\n                Get-AllScheduledTask | Get-Task | ForEach-Object {\n                    $Value = $null\n                    $Value = if (\n                        ($node = ([xml]$_.XML).Task.get_ChildNodes() | Where-Object Name -eq 'Actions' ).HasChildNodes\n                    ) {\n                        # $node can have Exec or comHandler or both childs (ex: MediaCenter tasks)\n                        switch ($node.get_ChildNodes().Name) {\n                            Exec {\n                                $subnode = ($node.get_ChildNodes() | Where-Object { $_.Name -eq 'Exec'})\n                                if ($subnode.get_ChildNodes() | Where-Object Name -eq 'Arguments' | Select-Object -ExpandProperty '#text') {\n                                    '{0} {1}' -f ($subnode.get_ChildNodes() | Where-Object Name -eq 'Command' | Select-Object -ExpandProperty '#text'), \n                                    ($subnode.get_ChildNodes() | Where-Object Name -eq 'Arguments' | Select-Object -ExpandProperty '#text');\n                                } else {\n                                    $subnode.get_ChildNodes() | Where-Object Name -eq 'Command' | Select-Object -ExpandProperty '#text' ; \n                                }\n                                break;\n                            }\n                            ComHandler {\n                                $subnode = ($node.get_ChildNodes() | Where-Object { $_.Name -eq 'ComHandler'})\n                                if ($subnode.get_ChildNodes()| Where-Object Name -eq 'Data' | Select-Object -ExpandProperty InnerText) {\n                                    '{0} {1}'-f ($subnode.get_ChildNodes() | Where-Object Name -eq 'ClassId' | Select-Object -ExpandProperty '#text'),\n                                    ($subnode.get_ChildNodes() | Where-Object Name -eq 'Data' | Select-Object -ExpandProperty InnerText); \n                                } else {\n                                    $subnode.get_ChildNodes() | Where-Object Name -eq 'ClassId' | Select-Object -ExpandProperty '#text'; \n                                }\n                                break;\n                            }\n                            default {}\n                        }\n                    }\n\n                    @{\n                        Path = (Join-Path -Path \"$($env:systemroot)\\system32\\Tasks\" -ChildPath \"$($_.Path)\\$($_.Name)\") ;\n                        Item = $_.Name\n                        Value =  $Value ;\n                        Category = 'Task' ;\n                    }\n                }\n\n                #endregion Scheduled Tasks\n            }\n            if ($All -or $Winlogon) {\n                Write-Verbose -Message 'Looking for Winlogon entries'\n                #region Winlogon\n\t            $Category = @{ Category = 'Winlogon'}\n                Get-RegValue -Path 'HKLM:\\SYSTEM\\Setup' -Name 'CmdLine' @Category\n\n\t            'Credential Providers','Credential Provider Filters','PLAP Providers' | ForEach-Object {\n\t\t            $key = Join-Path -Path 'HKLM:\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Authentication' -ChildPath $_\n\t\t            (Get-Item -Path $key).GetSubKeyNames() | ForEach-Object -Process {\n                        @{\n                            Path = $key\n                            Item = $_\n                            Value = (Get-ItemProperty -Path (Join-Path -Path 'HKLM:\\SOFTWARE\\Classes\\CLSID' -ChildPath \"$($_)\\InprocServer32\") -Name '(default)' -ErrorAction SilentlyContinue).'(default)'\n                            Category = 'Winlogon'\n                        }\t\t\t\n\t\t            }\n\t            }  \n                <# # deprecated\n\t            'System','SaveDumpStart' | ForEach-Object {\n\t\t            Get-RegValue -Path 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon' -Name $_ @Category\t\n\t            }\n                #>\n    \n                # Notify doesn't exist on Windows 8.1\n                <# # deprecated\n                if (Test-Path -Path 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\Notify' -PathType Container) {\n\t                $key = 'HKLM:\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\Notify'\n                    (Get-Item -Path $key).GetSubKeyNames() | ForEach-Object -Process {\n\t\t                Get-RegValue -Path \"$key\\$($_)\" -Name 'DLLName' @Category\t\n\t                }\n                }\n                #>\n\n\t            if (Test-Path -Path 'HKLM:\\System\\CurrentControlSet\\Control\\BootVerificationProgram' -PathType Container) {\n\t\t            Get-RegValue -Path 'HKLM:\\System\\CurrentControlSet\\Control\\BootVerificationProgram' -Name 'ImagePath' @Category\n\t            }\n                #endregion Winlogon\n\n                #region User Winlogon\n\n                Get-RegValue -Path 'HKCU:\\SOFTWARE\\Policies\\Microsoft\\Windows\\Control Panel\\Desktop' -Name 'Scrnsave.exe' @Category\n\n                Get-RegValue -Path 'HKCU:\\Control Panel\\Desktop' -Name 'Scrnsave.exe' @Category\n\n                #endregion User Winlogon\n            }\n            if ($All -or $WMI) {\n                Write-Verbose -Message 'Looking for WMI Database entries'\n\n                # Temporary events created with Register-CimIndicationEvent or Register-WMIEvent\n                <#\n                Get-EventSubscriber -ErrorAction SilentlyContinue | ForEach-Object -Process {\n                    $job = $_ | Select-Object -ExpandProperty Action\n                    if ($job.Command) {\n                        Write-Warning -Message 'A temporary WMI Event subscription was found'\n                    }\n                }\n                #>\n                # Permanent events\n                Get-WMIObject -Namespace root\\Subscription -Class __EventConsumer -ErrorAction SilentlyContinue| Where-Object { $_.__CLASS -eq 'ActiveScriptEventConsumer' } | ForEach-Object {\n                    if ($_.ScriptFileName) {\n                        @{\n                            Path = $_.__PATH ;\n                            Item = $_.Name\n                            Value =  $_.ScriptFileName ;\n                            Category = 'WMI' ;\n                        }\n                    \n                    } elseif ($_.ScriptText) {\n                        @{\n                            Path = $_.__PATH ;\n                            Item = $_.Name\n                            Value =  $null ;\n                            Category = 'WMI' ;\n                        }\n                    } \n                }\n\n                Get-WMIObject -Namespace root\\Subscription -Class __EventConsumer -ErrorAction SilentlyContinue| Where-Object { $_.__CLASS -eq 'CommandlineEventConsumer' } | ForEach-Object {\n                        @{\n                            Path = $_.__PATH ;\n                            Item = $_.Name\n                            Value =  \"$($_.WorkingDirectory)$($_.ExecutablePath)\" ;# $($_.CommandLineTemplate)\" ;\n                            Category = 'WMI' ;\n                        }\n                }\n                # List recursiveley registered and resolved WMI providers\n                Get-WmiObject -Namespace root -Recurse -Class __Provider -List -ErrorAction SilentlyContinue | ForEach-Object {\n                    Get-WmiObject -Namespace $_.__NAMESPACE -Class $_.__CLASS -ErrorAction SilentlyContinue | ForEach-Object {\n                        Write-Verbose -Message \"Found provider clsid $($_.CLSID) from under the $($_.__NAMESPACE) namespace\"\n                        if (($clsid = (Get-ItemProperty -Path \"HKLM:\\SOFTWARE\\Classes\\CLSID\\$($_.CLSID)\\InprocServer32\" -Name '(default)' -ErrorAction SilentlyContinue).'(default)')) {\n                            @{\n                                Path = $_.__PATH ;\n                                Item = $_.Name\n                                Value = $clsid\n                                Category = 'WMI' ;\n                            }\n                        }\n                    }\n                }\n            }\n        }\n        End {\n        }\n    }\n\n    Function Get-PSPrettyAutorun {\n        [CmdletBinding()]\n        Param(\n            [Parameter(Mandatory,ValueFromPipeLine)]\n            [system.object[]]$RawAutoRun\n        )\n        Begin {}\n        Process {\n            $RawAutoRun | ForEach-Object {\n                $Item = $_\n                Switch ($Item.Category) {\n                    Task {\n                        Write-Verbose -Message \"Reading Task $($Item.Path)\"\n                        $Item | Add-Member -MemberType NoteProperty -Name ImagePath -Value $(\n                            Switch -Regex ($Item.Value ) {\n                                #GUID\n                                '^(\\{)?[A-Za-z0-9]{4}([A-Za-z0-9]{4}\\-?){4}[A-Za-z0-9]{12}(\\})?' { \n                                    # $clsid = ($_ -split '\\s')[0]\n                                    $clsid = ([system.guid]::Parse( ($_ -split '\\s')[0])).ToString('B')\n                                    if (Test-Path (Join-Path -Path 'HKLM:\\SOFTWARE\\Classes\\CLSID' -ChildPath \"$($clsid)\\InprocServer32\") -PathType Container) {\n                                        Write-Verbose -Message 'Reading from InprocServer32'\n                                        (Get-ItemProperty -Path (Join-Path -Path 'HKLM:\\SOFTWARE\\Classes\\CLSID' -ChildPath \"$($clsid)\\InprocServer32\") -Name '(default)' -ErrorAction SilentlyContinue).'(default)' \n                                    } elseif (Test-Path (Join-Path -Path 'HKLM:\\SOFTWARE\\Classes\\CLSID' -ChildPath \"$($clsid)\\LocalServer32\") -PathType Container) {\n                                        Write-Verbose -Message 'Reading from LocalServer32'\n                                        (Get-ItemProperty -Path (Join-Path -Path 'HKLM:\\SOFTWARE\\Classes\\CLSID' -ChildPath \"$($clsid)\\LocalServer32\") -Name '(default)' -ErrorAction SilentlyContinue).'(default)'\n                                    } else {\n                                        try {\n                                            Write-Verbose -Message 'Reading from AppID'\n                                            # $appid = (Get-ItemProperty -Path (Join-Path -Path 'HKLM:\\SOFTWARE\\Classes\\CLSID' -ChildPath \"$($clsid)\") -Name 'AppId' -ErrorAction Stop).'AppId'\n                                            \"$($env:systemroot)\\system32\\sc.exe\"\n                                        } catch {\n                                            # Write-Warning -Message \"AppId not found for $clsid\"\n                                        }\n                                    }\n                                    break\n                                }\n                                # Rundll32\n                                '^((%windir%|%(s|S)ystem(r|R)oot%)\\\\system32\\\\)?rundll32\\.exe\\s(/[a-z]\\s)?.*,.*' {\n                                    Join-Path -Path \"$($env:systemroot)\\system32\" -ChildPath (\n                                        @([regex]'^((%windir%|%(s|S)ystem(r|R)oot%)\\\\system32\\\\)?rundll32\\.exe\\s(/[a-z]\\s)?(%windir%\\\\system32\\\\)?(?<File>.*),').Matches($_) | \n                                        Select-Object -Expand Groups | Select-Object -Last 1 | Select-Object -ExpandProperty Value\n                                    )\n                                    break\n                                }\n                                # Windir\\system32\n                                '^(%windir%|%(s|S)ystem(r|R)oot%|C:\\\\[Ww][iI][nN][dD][oO][Ww][sS])\\\\(s|S)ystem32\\\\.*\\.(exe|vbs)' {\n                                    Join-Path -Path \"$($env:systemroot)\\system32\" -ChildPath (\n                                        @([regex]'^(%windir%|%(s|S)ystem(r|R)oot%|C:\\\\[Ww][iI][nN][dD][oO][Ww][sS])\\\\(s|S)ystem32\\\\(?<File>.*\\.(exe|vbs))(\\s)?').Matches($_) | \n                                        Select-Object -Expand Groups | Select-Object -Last 1 | Select-Object -ExpandProperty Value\n                                    )\n                                    break\n                                }\n                                # windir\\somethingelse\n                                '^(%windir%|%(s|S)ystem(r|R)oot%|C:\\\\[Ww][iI][nN][dD][oO][Ww][sS])\\\\.*\\\\.*\\.(exe|vbs)' {\n                                    Join-Path -Path \"$($env:systemroot)\" -ChildPath (\n                                        @([regex]'^(%windir%|%(s|S)ystem(r|R)oot%|C:\\\\[Ww][iI][nN][dD][oO][Ww][sS])\\\\(?<File>.*\\\\.*\\.(exe|vbs))(\\s)?').Matches($_) | \n                                        Select-Object -Expand Groups | Select-Object -Last 1 | Select-Object -ExpandProperty Value\n                                    )\n                                    break\n                                }\n                                # special W7 case with media center\n                                '^%SystemRoot%\\\\ehome\\\\.*\\s' {\n                                    # \"$($env:systemroot)\\ehome\\ehrec.exe\"\n                                    Join-Path -Path \"$($env:systemroot)\\ehome\" -ChildPath \"$(\n                                        @([regex]'^%SystemRoot%\\\\ehome\\\\(?<FileName>.*)\\s').Matches($_) | \n                                        Select-Object -Expand Groups | Select-Object -Last 1 | Select-Object -ExpandProperty Value\n                                    ).exe\"\n                                    break\n                                }\n                                # ProgramFiles\n                                '^\"?(C:\\\\Program\\sFiles|%ProgramFiles%)\\\\' {\n                                    Join-Path -Path \"$($env:ProgramFiles)\" -ChildPath (\n                                        @([regex]'^\"?(C:\\\\Program\\sFiles|%ProgramFiles%)\\\\(?<File>.*\\.exe)(\"|\\s)?').Matches($_) | \n                                        Select-Object -Expand Groups | Select-Object -Last 1 | Select-Object -ExpandProperty Value\n                                    )                                        \n                                    break\n                                }\n                                # ProgramFilesx86\n                                '^\"?(C:\\\\Program\\sFiles\\s\\(x86\\)|%ProgramFiles\\(x86\\)%)\\\\' {\n                                    Join-Path -Path \"$(${env:ProgramFiles(x86)})\" -ChildPath (\n                                        @([regex]'^\"?(C:\\\\Program\\sFiles\\s\\(x86\\)|%ProgramFiles\\(x86\\)%)\\\\(?<File>.*\\.exe)(\"|\\s)?').Matches($_) | \n                                        Select-Object -Expand Groups | Select-Object -Last 1 | Select-Object -ExpandProperty Value\n                                    )\n                                    break\n                                }\n                                # special powershell.exe\n                                '^[pP][oO][wW][eE][rR][sS][hH][eE][lL]{2}\\.[eE][xX][eE](\\s)?' {\n                                    \"$($env:systemroot)\\system32\\WindowsPowerShell\\v1.0\\powershell.exe\"\n                                    break\n                                }\n                                # C:\\users? \n                                '^[A-Za-z]:\\\\' {\n                                    $_\n                                    break;\n                                }\n                                # FileName.exe\n                                '[a-zA-Z0-9]*\\.exe(\\s)?' {\n                                # '[a-zA-Z0-9]*(\\.exe\\s)?' {\n                                    Join-Path -Path \"$($env:systemroot)\\system32\" -ChildPath \"$(\n                                        @([regex]'^(?<FileName>[a-zA-Z0-9]*)(\\.exe\\s)?').Matches($_) |\n                                        Select-Object -Expand Groups | Select-Object -Last 1 | Select-Object -ExpandProperty Value\n                                        ).exe\"\n                                    break\n                                }\n                                '^aitagent(\\s/increment)?' {\n                                    \"$($env:systemroot)\\system32\\aitagent.exe\"\n                                    break\n                                }\n                                default {\n                                    $_\n                                }\n                        } #endof switch\n                        ) -Force -PassThru\n\n                    break;\n                    }\n                    AppInit {\n                        if ($Item.Value -eq [string]::Empty) {\n                            $Item | Add-Member -MemberType NoteProperty -Name ImagePath -Value $null -Force -PassThru\n                        } else {\n                            # Switch ? malware example\n                            $Item | Add-Member -MemberType NoteProperty -Name ImagePath -Value \"$($Item.Value)\" -Force -PassThru\n                        }\n                        break\n                    }\n                    'Boot Execute' {\n                        $Item | Add-Member -MemberType NoteProperty -Name ImagePath -Value $(\n                            Switch -Regex ($Item.Value) {\n                                '^autocheck\\sautochk\\s' {\n                                    \"$($env:SystemRoot)\\system32\\autochk.exe\"\n                                    break;\n                                }\n                                default {\n                                    $Item.Value\n                                }\n                            }\n                        ) -Force -PassThru\n                        break\n                    }\n                    Codecs {\n                        $Item | Add-Member -MemberType NoteProperty -Name ImagePath -Value $(\n                        Switch -Regex ($Item.Value) {\n                            '^[A-Z]:\\\\Windows\\\\' {\n                                if ($Item.Path -match 'Wow6432Node') {\n                                    $_ -replace 'system32','SysWOW64'\n                                } else {\n                                    $_\n                                }\n                                break\n                            }\n                            # '^[A-Z]:\\\\Program\\sFiles' {\n                            '^[A-Z]:\\\\[Pp]rogra' {\n                                $_  | Get-NormalizedFileSystemPath\n                                break\n                            }\n                            default {\n                                if ($Item.Path -match 'Wow6432Node') {\n                                    Join-Path \"$($env:systemroot)\\Syswow64\" -ChildPath $_\n                                } else {\n                                    Join-Path \"$($env:systemroot)\\System32\" -ChildPath $_\n                                }\n                            }\n                        }\n                        ) -Force -PassThru\n                        break\n                    }\n                    Drivers {\n                        $Item | Add-Member -MemberType NoteProperty -Name ImagePath -Value $(\n                            switch -Regex ($Item.Value) {\n                                #'^\\\\SystemRoot\\\\System32\\\\drivers\\\\' {\n                                '^\\\\SystemRoot\\\\System32\\\\' {\n                                    $_ -replace '\\\\Systemroot',\"$($env:systemroot)\"\n                                    break;\n                                }\n                                <#\n                                '^System32\\drivers\\\\' {\n                                    Join-Path -Path \"$($env:systemroot)\" -ChildPath $_\n                                    break;\n                                }\n                                #>\n                                '^System32\\\\[dD][rR][iI][vV][eE][rR][sS]\\\\' {\n                                    Join-Path -Path \"$($env:systemroot)\" -ChildPath $_\n                                    break;\n                                }\n                                <#\n                                '^system32\\\\DRIVERS\\\\' {\n                                    Join-Path -Path \"$($env:systemroot)\" -ChildPath $_\n                                    break;\n                                }\n                                #>\n                                '^\\\\\\?\\?\\\\C:\\\\Windows\\\\system32\\\\drivers' {\n                                    $_ -replace '\\\\\\?\\?\\\\',''\n                                    break;\n                                }\n                                '^System32\\\\CLFS\\.sys' {\n                                    $_ -replace 'System32\\\\',\"$($env:systemroot)\\system32\\\"\n                                }\n                                '^\"?[A-Za-z]\\\\[Pp]rogram\\s[fF]iles.*\\\\(?<FilePath>.*\\\\\\.exe)\\s?' {\n                                    Join-Path -Path \"$($env:ProgramFiles)\" -ChildPath (\n                                        @([regex]'^\"?[A-Za-z]\\\\[Pp]rogram\\s[fF]iles.*\\\\(?<FilePath>.*\\\\\\.exe)\\s?').Matches($_) | \n                                        Select-Object -Expand Groups | Select-Object -Last 1 | Select-Object -ExpandProperty Value\n                                    )                                        \n                                    break\n                                }\n                                'SysmonDrv.sys' {\n                                    $env:PATH -split ';'| ForEach-Object { \n                                        Get-ChildItem -Path $_\\*.sys -Include SysmonDrv.sys -Force -EA 0 \n                                    } | Select-Object -First 1 -ExpandProperty FullName\n                                    break\n                                }\n                                default {\n                                    $_\n                                }\n                        }) -Force -PassThru\n                        break\n                    }\n                    Explorer {\n                        $Item | Add-Member -MemberType NoteProperty -Name ImagePath -Value $(\n                            if ($Item.Value) {\n                                if ($Item.Value -match '^[A-Z]:\\\\') {\n                                    if ($Item.Path -match 'Wow6432Node') {\n                                        $Item.Value -replace 'system32','syswow64' | Get-NormalizedFileSystemPath\n                                    } else {\n                                        $Item.Value | Get-NormalizedFileSystemPath\n                                    }\n                                } else {\n                                    if ($Item.Path -match 'Wow6432Node') {\n                                        Join-Path -Path \"$($env:systemroot)\\syswow64\" -ChildPath $Item.Value\n                                    } else {\n                                        Join-Path -Path \"$($env:systemroot)\\system32\" -ChildPath $Item.Value\n                                    }\n                                }\n                            }\n                        ) -Force -PassThru\n                        break\n                    }\n                    'Image Hijacks' {\n                        $Item | Add-Member -MemberType NoteProperty -Name ImagePath -Value $null -Force -PassThru\n                        break\n                    }\n                    'Internet Explorer' {\n                        if ($Item.Item -ne 'Locked') {\n                            $Item | Add-Member -MemberType NoteProperty -Name ImagePath -Value $(\n                                $Item.Value | Get-NormalizedFileSystemPath\n                            ) -Force -PassThru\n                        }\n                        break\n                    }\n                    'Known Dlls' {\n                        if ( (Test-Path -Path $Item.Value -PathType Container) -and ($Item.Item -match 'DllDirectory')) {\n                        } else {\n                            # Duplicate objects\n                            $Item | Add-Member -MemberType NoteProperty -Name ImagePath -Value $(\n                                Join-Path -Path \"$($env:SystemRoot)\\System32\" -ChildPath $Item.Value\n                            ) -Force -PassThru\n                            if ([environment]::Is64BitOperatingSystem) {\n                                $Item | Add-Member -MemberType NoteProperty -Name ImagePath -Value $(\n                                    Join-Path -Path \"$($env:SystemRoot)\\Syswow64\" -ChildPath $Item.Value\n                                ) -Force -PassThru\n                            }\n                        }\n                        break\n                    }\n                    Logon {\n                        $Item | Add-Member -MemberType NoteProperty -Name ImagePath -Value $(\n                            switch -Regex ($Item.Value) {\n                                '\\\\Rundll32\\.exe\\s' {\n                                    (($_ -split '\\s')[1] -split ',')[0]\n                                    break;\n                                }\n                                '\\\\Rundll32\\.exe\"' {\n                                    (($_ -split '\\s',2)[1] -split ',')[0] -replace '\"',''\n                                    break;\n                                }\n                                '^\"[A-Z]:\\\\Program' {\n                                    ($_ -split '\"')[1]\n                                    break;\n                                }\n                                '^\"[A-Z]:\\\\Windows' {\n                                    ($_ -split '\"')[1]\n                                    break;\n                                }\n                                'rdpclip' {\n                                    \"$($env:SystemRoot)\\system32\\$($_).exe\"\n                                    break\n                                }\n                                '^Explorer\\.exe$' {\n                                    \"$($env:SystemRoot)\\$($_)\"\n                                    break\n                                }\n                                # regsvr32.exe /s /n /i:U shell32.dll\n                                '^regsvr32\\.exe\\s/s\\s/n\\s/i:U\\sshell32\\.dll' {\n                                    if ($Item.Path -match 'Wow6432Node') {\n                                        \"$($env:SystemRoot)\\syswow64\\shell32.dll\"\n                                    }else {\n                                        \"$($env:SystemRoot)\\system32\\shell32.dll\"\n                                    }\n                                    break\n                                }\n                                '^C:\\\\Windows\\\\system32\\\\regsvr32\\.exe\\s/s\\s/n\\s/i:/UserInstall\\sC:\\\\Windows\\\\system32\\\\themeui\\.dll' {\n                                    if ($Item.Path -match 'Wow6432Node') {\n                                        \"$($env:SystemRoot)\\syswow64\\themeui.dll\"\n                                    }else {\n                                        \"$($env:SystemRoot)\\system32\\themeui.dll\"\n                                    }\n                                    break\n                                }\n                                '^C:\\\\Windows\\\\system32\\\\cmd\\.exe\\s/D\\s/C\\sstart\\sC:\\\\Windows\\\\system32\\\\ie4uinit\\.exe\\s\\-ClearIconCache' {\n                                    if ($Item.Path -match 'Wow6432Node') {\n                                        \"$($env:SystemRoot)\\syswow64\\ie4uinit.exe\"\n                                    }else {\n                                        \"$($env:SystemRoot)\\system32\\ie4uinit.exe\"\n                                    }\n                                    break\n                                }\n                                '^[A-Z]:\\\\Windows\\\\' {\n                                    if ($Item.Path -match 'Wow6432Node') {\n                                        (($_ -split '\\s')[0] -replace ',','') -replace 'System32','Syswow64'\n                                    } else {\n                                        (($_ -split '\\s')[0] -replace ',','')\n                                    }\n                                    break\n                                }\n                                '^[a-zA-Z0-9]+\\.(exe|dll)' {\n                                    if ($Item.Path -match 'Wow6432Node') {\n                                        Join-Path -Path \"$($env:SystemRoot)\\syswow64\" -ChildPath ($_ -split '\\s')[0]\n                                    } else {\n                                        Join-Path -Path \"$($env:SystemRoot)\\system32\" -ChildPath ($_ -split '\\s')[0]\n                                    }\n                                    break\n                                }\n                                '^RunDLL32\\s' {\n                                    Join-Path -Path \"$($env:SystemRoot)\\system32\" -ChildPath (($_ -split '\\s')[1] -split ',')[0]\n                                    break;\n                                }\n\n                                # ProgramFiles\n                                '^[A-Za-z]:\\\\Program\\sFiles\\\\' {\n                                    Join-Path -Path \"$($env:ProgramFiles)\" -ChildPath (\n                                        @([regex]'[A-Za-z]:\\\\Program\\sFiles\\\\(?<File>.*\\.exe)\\s?').Matches($_) | \n                                        Select-Object -Expand Groups | Select-Object -Last 1 | Select-Object -ExpandProperty Value\n                                    )                                        \n                                    break\n                                }\n                                # ProgramFilesx86\n                                '^[A-Za-z]:\\\\Program\\sFiles\\s\\(x86\\)\\\\' {\n                                    Join-Path -Path \"$(${env:ProgramFiles(x86)})\" -ChildPath (\n                                        @([regex]'[A-Za-z]:\\\\Program\\sFiles\\s\\(x86\\)\\\\(?<File>.*\\.exe)\\s?').Matches($_) | \n                                        Select-Object -Expand Groups | Select-Object -Last 1 | Select-Object -ExpandProperty Value\n                                    )\n                                    break\n                                }\n                                # C:\\Users\n                                '^\"[A-Za-z]:\\\\' {\n                                    ($_ -split '\"')[1]\n                                        break;\n                                }\n                                default {\n                                    Write-Verbose -Message \"default: $_\"\n                                    [string]::Empty\n                                    # $_\n                                }\n                            } \n                        ) -Force -PassThru\n                        break\n                    }\n                    'LSA Providers' {\n                        $Item | Add-Member -MemberType NoteProperty -Name ImagePath -Value $(\n                            if ($Item.Value -match '\\.dll$') {\n                                Join-Path -Path \"$($env:SystemRoot)\\system32\" -ChildPath $Item.Value\n                            } else {\n                                Join-Path -Path \"$($env:SystemRoot)\\system32\" -ChildPath \"$($Item.Value).dll\"\n                            }\n                        ) -Force -PassThru\n                        break\n                    }\n                    'Network Providers' {\n                        $Item | Add-Member -MemberType ScriptProperty -Name ImagePath -Value $({$this.Value}) -Force -PassThru\n                    }\n                    'Office Addins' {\n                        if ($Item.Path -match 'Wow6432Node' -and $Item.Value -imatch 'system32') {\n                            $Item.Value = $Item.Value -replace 'system32','syswow64'\n                        }\n                        if ($Item.Value) {\n                            $Item | Add-Member -MemberType NoteProperty -Name ImagePath -Value $(\n                                Switch -Regex ($Item.Value ) {\n                                    #GUID\n                                    '^(\\{)?[A-Za-z0-9]{4}([A-Za-z0-9]{4}\\-?){4}[A-Za-z0-9]{12}(\\})?' { \n                                        ([system.guid]::Parse( ($_ -split '\\s')[0])).ToString('B')\n                                        break\n                                    }\n                                    default {\n                                        $Item.Value -replace '\"','' | Get-NormalizedFileSystemPath\n                                    }\n                                }\n                            ) -Force -PassThru\n                        }\n                        break\n                    }\n                    'Print Monitors' {\n                        $Item | Add-Member -MemberType NoteProperty -Name ImagePath -Value $(\n                            Join-Path -Path \"$($env:SystemRoot)\\System32\" -ChildPath $Item.Value\n                        ) -Force -PassThru\n                        break\n                    }\n                    Services {\n                        $Item | Add-Member -MemberType NoteProperty -Name ImagePath -Value $(    \n                            switch -Regex ($Item.Value) {\n                            '^\"?[A-Za-z]:\\\\[Ww][iI][nN][dD][oO][Ww][sS]\\\\' {\n                                Join-Path -Path \"$($env:systemroot)\" -ChildPath (\n                                    @([regex]'^\"?[A-Za-z]:\\\\[Ww][iI][nN][dD][oO][Ww][sS]\\\\(?<FilePath>.*\\.(exe|dll))\\s?').Matches($_) | \n                                    Select-Object -Expand Groups | Select-Object -Last 1 | Select-Object -ExpandProperty Value\n                                )  \n                                break\n                            }\n                            '^\"?[A-Za-z]:\\\\[Pp]rogram\\s[fF]iles\\\\(?<FileName>.*\\.[eE][xX][eE])\\s?' {\n                                Join-Path -Path \"$($env:ProgramFiles)\" -ChildPath (\n                                    @([regex]'^\"?[A-Za-z]:\\\\[Pp]rogram\\s[fF]iles\\\\(?<FileName>.*\\.[eE][xX][eE])\\s?').Matches($_) | \n                                    Select-Object -Expand Groups | Select-Object -Last 1 | Select-Object -ExpandProperty Value\n                                )  \n                                break\n                            }\n                            '^\"?[A-Za-z]:\\\\[Pp]rogram\\s[fF]iles\\s\\(x86\\)\\\\(?<FileName>.*\\.[eE][xX][eE])\\s?' {\n                                Join-Path -Path \"$(${env:ProgramFiles(x86)})\" -ChildPath (\n                                    @([regex]'^\"?[A-Za-z]:\\\\[Pp]rogram\\s[fF]iles\\s\\(x86\\)\\\\(?<FileName>.*\\.[eE][xX][eE])\\s?').Matches($_) | \n                                    Select-Object -Expand Groups | Select-Object -Last 1 | Select-Object -ExpandProperty Value\n                                )  \n                                break\n                            }\n                            'winhttp.dll' {\n                                Join-Path -Path \"$($env:SystemRoot)\\System32\" -ChildPath 'winhttp.dll'\n                                break\n                            }\n                            'atmfd.dll' {\n                                Join-Path -Path \"$($env:SystemRoot)\\System32\" -ChildPath 'atmfd.dll'\n                                break\n                            }\n                            default {\n                                $_\n                            }\n\n                        }) -Force -PassThru\n                        break\n                    }\n                    Winlogon {\n                        # this works on W8.1\n                        # $Item | Add-Member -MemberType ScriptProperty -Name ImagePath -Value $({$this.Value}) -Force -PassThru\n                        # for backward compatibility with W7 we do:\n                        $Item | Add-Member -MemberType NoteProperty -Name ImagePath -Value $(\n                            Switch -Regex ($Item.Value) {\n                                '^[a-zA-Z0-9]*\\.[dDlL]{3}' {\n                                    Join-Path -Path \"$($env:SystemRoot)\\System32\" -ChildPath $Item.Value\n                                    break\n                                }\n                                default {\n                                    $_;\n                                }\n                            }\n                        ) -Force -PassThru\n                        break\n                    }\n                    'Winsock Providers' {\n                        $Item | Add-Member -MemberType NoteProperty -Name ImagePath -Value $(\n                            Switch -Regex ($Item.Value) {\n                                '^%SystemRoot%\\\\system32\\\\' {\n                                    $_ -replace '%SystemRoot%',\"$($env:SystemRoot)\";\n                                    break;\n                                }\n                                default {\n                                    $_;\n                                }\n                            }\n                        ) -Force -PassThru\n                        break\n                    }\n                    WMI {\n                        if ($Item.Value) {\n                            $Item | Add-Member -MemberType NoteProperty -Name ImagePath -Value $($Item.Value) -Force -PassThru\n                            \n                        } else {\n                            $Item | Add-Member -MemberType NoteProperty -Name ImagePath -Value $null -Force -PassThru\n                        }\n                        break\n                    }\n                    default {\n                    }\n                }\n            }\n        }\n        End {}\n    }\n\n\n    Function Add-PSAutoRunExtendedInfo {\n        [CmdletBinding()]\n        Param(\n            [Parameter(Mandatory,ValueFromPipeLine)]\n            [system.object[]]$RawAutoRun\n        )\n        Begin {}\n        Process {\n            $RawAutoRun | ForEach-Object {\n                $o = [pscustomobject]@{\n                        Path = $_.Path ;\n                        Item = $_.Item ;\n                        Category = $_.Category ;\n                        Value = $_.Value\n                        ImagePath = $_.ImagePath ;\n                        Size = $null;\n                        LastWriteTime = $null;\n                        Version = $null;\n                    }\n                If ($_.ImagePath) {\n                    try {\n                        $extinfo = Get-Item -Path $_.ImagePath -ErrorAction Stop\n                        $o.Size = $extinfo.Length;\n                        $o.Version = $extinfo.VersionInfo.ProductVersion;\n                        $o.LastWriteTime = $extinfo.LastWriteTime;\n                        $o\n                    } catch {\n                        $o\n                    }\n                } else {\n                    $o\n                }\n            }\n        }\n        End{}\n    }\n    Function Add-PSAutoRunHash {\n        [CmdletBinding()]\n        Param(\n            [Parameter(Mandatory,ValueFromPipeLine)]\n            [system.object[]]$RawAutoRun,\n            [Switch]$ShowFileHash\n        )\n        Begin {}\n        Process {\n            $RawAutoRun | ForEach-Object {\n                If ($ShowFileHash) {\n                    if ($_.ImagePath) {\n                        If (Test-Path -Path $($_.ImagePath) -PathType Leaf) {\n                            $_ | Add-Member -MemberType NoteProperty -Name MD5 -Value $(\n                                (Get-FileHash -Path $($_.ImagePath) -Algorithm MD5).Hash\n                            ) -Force -PassThru |\n                            Add-Member -MemberType NoteProperty -Name SHA1 -Value $(\n                                (Get-FileHash -Path $($_.ImagePath) -Algorithm SHA1).Hash\n                            ) -Force -PassThru |\n                            Add-Member -MemberType NoteProperty -Name SHA256 -Value $(\n                                (Get-FileHash -Path $($_.ImagePath) -Algorithm SHA256).Hash\n                            ) -Force -PassThru\n                        } else {\n                            $_ | Add-Member -MemberType NoteProperty -Name MD5 -Value $null -Force -PassThru |\n                            Add-Member -MemberType NoteProperty -Name SHA1 -Value $null -Force -PassThru |\n                            Add-Member -MemberType NoteProperty -Name SHA256 -Value $null -Force -PassThru\n                        }\n                    } else {\n                        $_ | Add-Member -MemberType NoteProperty -Name MD5 -Value $null -Force -PassThru |\n                        Add-Member -MemberType NoteProperty -Name SHA1 -Value $null -Force -PassThru |\n                        Add-Member -MemberType NoteProperty -Name SHA256 -Value $null -Force -PassThru\n                    }\n                } else {\n                    $_\n                }\n            }\n        }\n        End {}\n    }\n\n    Function Add-PSAutoRunAuthentiCodeSignature {\n        [CmdletBinding()]\n        Param(\n            [Parameter(Mandatory,ValueFromPipeLine)]\n            [system.object[]]$RawAutoRun,\n            [Switch]$VerifyDigitalSignature\n        )\n        Begin {}\n        Process {\n            $RawAutoRun | ForEach-Object {\n                If ($VerifyDigitalSignature) {\n                    if ($_.ImagePath) {\n                        If (Test-Path -Path $_.ImagePath -PathType Leaf) {\n                            \n                            ## Add the signature status to the entry\n                            $signature = Get-AuthenticodeSignature -FilePath $_.ImagePath -ErrorAction Stop\n                            $signed = switch ($signature.Status) {\n                                'Valid' {\n                                    $true\n                                    break\n                                }\n                                'NotSigned' {\n                                    $false\n                                    break\n                                }\n                                default {\n                                    $false\n                                }\n                            }\n                            $_ = $_ | Add-Member -MemberType NoteProperty -Name Signed -Value $signed -Force -PassThru\n                            \n                            ## Add a note whether this is an OS binary to allow for easy filtering:\n                            ## Get-PSAutorun -VerifyDigitalSignature | ? { -not $_.IsOSBinary }\n                            if($signature.IsOSBinary)\n                            {\n                                $_ = $_ | Add-Member -MemberType NoteProperty -Name IsOSBinary -Value $signature.IsOSBinary -Force -PassThru\n                            }\n\n                            ## Add the signer itself\n                            $_ | Add-Member -MemberType NoteProperty -Name Publisher -Value $signature.SignerCertificate.Subject -Force -PassThru\n                        }\n                    } else {\n                        $_ = $_ | Add-Member -MemberType NoteProperty -Name Signed -Value $null -Force -PassThru\n                        $_ = $_ | Add-Member -MemberType NoteProperty -Name IsOSBinary -Value $null -Force -PassThru\n                        $_ | Add-Member -MemberType NoteProperty -Name Publisher -Value $null -Force -PassThru\n                    }\n                } else {\n                    $_\n                }\n            }\n        }\n        End{}\n    }\n\n    #endregion Helperfunctions\n\n}\nProcess {\n    if ($PSBoundParameters.ContainsKey('ShowFileHash')) {\n        $GetHash = $true\n    } else {\n        $GetHash = $false\n    }\n    if ($PSBoundParameters.ContainsKey('VerifyDigitalSignature')) {\n        $GetSig = $true\n    } else {\n        $GetSig = $false\n    }\n    Get-PSRawAutoRun @PSBoundParameters | \n    Get-PSPrettyAutorun | \n    Add-PSAutoRunExtendedInfo |\n    Add-PSAutoRunHash -ShowFileHash:$GetHash |\n    Add-PSAutoRunAuthentiCodeSignature -VerifyDigitalSignature:$GetSig\n}\nEnd {}\n}\n\n<#\nGet-PSAutorun -BootExecute -AppinitDLLs\nGet-PSAutorun -All | Format-Table -Property Path,ImagePath,Category \nGet-PSAutorun -Logon -LSAsecurityProviders | Format-Table -Property Path,ImagePath,Category\nGet-PSAutorun -All -ShowFileHash -VerifyDigitalSignature\nGet-PSAutorun -ServicesAndDrivers | ? path -match 'OSE' | fl *\nGet-PSAutorun -ServicesAndDrivers | ? path -match 'sysmon' | fl *\nGet-PSAutorun -ServicesAndDrivers | ? path -match 'psexesvc' | fl *\nGet-PSAutorun -OfficeAddins | Format-Table -Property Path,ImagePath,Category\nGet-PSAutorun -WMI -VerifyDigitalSignature | Where { -not $_.isOSBinary }\n\n# From 11.70 to 12.0\n    +HKLM\\SYSTEM\\CurrentControlSet\\Control\\Lsa\\OSConfig\\Security Packages\n    +WMI Database Entries\n# From 12.0 to 12.3\n    -HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\System\n    -HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\Notify\n    -HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\SaveDumpStart\n    +HKCU\\SOFTWARE\\Classes\\Htmlfile\\Shell\\Open\\Command\\(Default)\n    +HKLM\\SOFTWARE\\Classes\\Htmlfile\\Shell\\Open\\Command\\(Default)\n# From 12.3 to 13.4\n    +HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\GpExtensions\n    +HKLM\\Software\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon\\AlternateShells\\AvailableShells\n    +HKCU\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\Run\n    +HKCU\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\RunOnce\n    +HKCU\\Software\\Classes\\Clsid\\{AB8902B4-09CA-4bb6-B78D-A8F59079A8D5}\\Inprocserver32\n    +Office Addins\n# From 13.4 to 13.5\n    +HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Font Drivers\n# From 13.5 to 13.51\n    +HKLM\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Terminal Server\\Install\\Software\\Microsoft\\Windows\\CurrentVersion\\RunonceEx\n    +HKLM\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnceEx\n    +HKLM\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\RunOnceEx\n    +HKCU\\SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\RunOnceEx\n    +HKCU\\SOFTWARE\\Wow6432Node\\Microsoft\\Windows\\CurrentVersion\\RunOnceEx\n    +HKCU\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Terminal Server\\Install\\Software\\Microsoft\\Windows\\CurrentVersion\\RunonceEx\n# From 13.51 to 13.61\n    +HKLM\\SOFTWARE\\Microsoft\\Office test\\Special\\Perf\\(Default)\n    +HKCU\\SOFTWARE\\Microsoft\\Office test\\Special\\Perf\\(Default)\n# From 13.61 to 13.62\n    +HKLM\\SYSTEM\\CurrentControlSet\\Control\\Lsa\\Security Packages\n# From 13.62 to 13.7\n    +HKLM\\SYSTEM\\CurrentControlSet\\Control\\Print\\Providers\n#>"
  },
  {
    "path": "ACE-Management/PS-ACE/Scripts/ACE_Get-PSIProcess.ps1",
    "content": "﻿function Start-AceScript\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $SweepId,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $ScanId,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $RoutingKey,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Thumbprint\n    )\n\n    $HostFQDN = Get-WmiObject Win32_ComputerSystem -Property 'Name','Domain' | ForEach-Object {\"$($_.Name).$($_.Domain)\"}\n    $ResultDate = (Get-Date).ToString(\"yyyyMMddThhmmssmsmsZ\")\n\n    $dataList = New-Object -TypeName System.Collections.Generic.List['string']\n\n    foreach($o in (Get-PSIProcess -ReturnHashtables))\n    {\n        $o.Add('ComputerName', $HostFQDN)\n        $o.Add('ScanType', 'Process')\n        $o.Add('SweepId', $SweepId)\n        $o.Add('ScanId', $ScanId)\n        $o.Add('ResultDate', $ResultDate)\n\n        $message = ConvertTo-JsonV2 -InputObject $o\n        $dataList.Add($message)\n    }\n\n    $props = @{\n        ComputerName = $HostFQDN\n        ScanType     = 'Process'\n        RoutingKey   = $RoutingKey\n        ResultDate   = $ResultDate\n        ScanId       = $ScanId\n        Data         = $dataList.ToArray()\n    }\n\n    $body = (ConvertTo-JsonV2 -InputObject $props)\n    \n    Write-Output $body\n\n    #Invoke-AceWebRequest -Thumbprint $Thumbprint -Uri \"$($Uri)/ace/result/$($SweepId)\" -Body $body\n}\n\nfunction ConvertTo-JsonV2 \n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        $InputObject\n    )\n\n    Begin \n    {\n        $null = [System.Reflection.Assembly]::LoadWithPartialName(\"System.Web.Extensions\")\n        $Serializer = New-Object System.Web.Script.Serialization.JavaScriptSerializer\n    }\n\n    Process \n    {\n        try \n        {\n            $Serializer.Serialize($InputObject)\n        } \n        catch \n        {\n            Write-Error $_\n        }    \n    }\n}\n\nfunction Invoke-AceWebRequest\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Thumbprint,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Body\n    )\n\n    [Net.ServicePointManager]::ServerCertificateValidationCallback = {\n        $Thumbprint = $Thumbprint\n        $certificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]$args[1]\n    \n        if ($certificate -eq $null)\n        {\n            $Host.UI.WriteErrorLine(\"Null certificate.\")\n            return $true\n        }\n    \n        if ($certificate.Thumbprint -eq $Thumbprint)\n        {\n            return $true\n        }\n        else\n        {\n            $Host.UI.WriteErrorLine(\"Thumbprint mismatch. Certificate thumbprint $($certificate.Thumbprint)\")\n        }\n    \n        return $false\n    }\n\n    try\n    {\n        Write-Host \"URI: $($Uri)\"\n\n        # Create web request\n        $WebRequest = [Net.WebRequest]::Create($uri)\n        $WebRequest.Method = 'Post'\n        $WebRequest.ContentType = 'application/json'\n        $WebRequest.Headers.Add('X-API-Version:1.0')\n\n        $byteArray = [System.Text.Encoding]::UTF8.GetBytes($Body)\n        $Webrequest.ContentLength = $byteArray.Length\n        \n        $dataStream = $Webrequest.GetRequestStream()            \n        $dataStream.Write($byteArray, 0, $byteArray.Length)\n        $dataStream.Close()\n\n        # Get response stream\n        $ResponseStream = $Webrequest.GetResponse().GetResponseStream()\n    \n        # Create a stream reader and read the stream returning the string value.\n        $StreamReader = New-Object System.IO.StreamReader -ArgumentList $ResponseStream\n        $StreamReader.ReadToEnd()\n    }\n    catch\n    {\n        Write-Error \"Failed: $($_.exception.innerexception.message)\"\n    }\n}\n\nfunction Get-PSIProcess {\n<#\n    .SYNOPSIS\n\n        Returns detailed information about the current running processes.\n\n        Author: Lee Christensen (@tifkin_)\n        License: BSD 3-Clause\n        Required Dependencies: None\n        Optional Dependencies: None\n\n#>\n    [CmdletBinding()]\n    Param (\n        [switch]\n        $ReturnHashtables\n    )\n\n    # TODO: Optimize this cmdlet...\n\n    begin\n    {\n        # Thanks to https://p0w3rsh3ll.wordpress.com/2015/02/05/backporting-the-get-filehash-function/\n        function Get-DIGSFileHash\n        {\n            [CmdletBinding(DefaultParameterSetName = \"Path\")]\n            param\n            (\n                [Parameter(Mandatory=$true, ParameterSetName=\"Path\", Position = 0)]\n                [System.String[]]\n                $Path,\n\n                [Parameter(Mandatory=$true, ParameterSetName=\"LiteralPath\", ValueFromPipelineByPropertyName = $true)]\n                [Alias(\"PSPath\")]\n                [System.String[]]\n                $LiteralPath,\n        \n                [Parameter(Mandatory=$true, ParameterSetName=\"Stream\")]\n                [System.IO.Stream]\n                $InputStream,\n\n                [ValidateSet(\"SHA1\", \"SHA256\", \"SHA384\", \"SHA512\", \"MACTripleDES\", \"MD5\", \"RIPEMD160\")]\n                [System.String]\n                $Algorithm=\"SHA256\"\n            )\n    \n            begin\n            {\n                # Construct the strongly-typed crypto object\n                $hasher = [System.Security.Cryptography.HashAlgorithm]::Create($Algorithm)\n            }\n    \n            process\n            {\n                if($PSCmdlet.ParameterSetName -eq \"Stream\")\n                {\n                    Get-DIGSStreamHash -InputStream $InputStream -RelatedPath $null -Hasher $hasher\n                }\n                else\n                {\n                    $pathsToProcess = @()\n                    if($PSCmdlet.ParameterSetName  -eq \"LiteralPath\")\n                    {\n                        $pathsToProcess += Resolve-Path -LiteralPath $LiteralPath | Foreach-Object { $_.ProviderPath }\n                    }\n                    if($PSCmdlet.ParameterSetName -eq \"Path\")\n                    {\n                        $pathsToProcess += Resolve-Path $Path | Foreach-Object { $_.ProviderPath }\n                    }\n\n                    foreach($filePath in $pathsToProcess)\n                    {\n                        if(Test-Path -LiteralPath $filePath -PathType Container)\n                        {\n                            continue\n                        }\n\n                        try\n                        {\n                            # Read the file specified in $FilePath as a Byte array\n                            [system.io.stream]$stream = [system.io.file]::OpenRead($filePath)\n                            Get-DIGSStreamHash -InputStream $stream  -RelatedPath $filePath -Hasher $hasher\n                        }\n                        catch [Exception]\n                        {\n                            $errorMessage = 'FileReadError {0}:{1}' -f $FilePath, $_\n                            Write-Error -Message $errorMessage -Category ReadError -ErrorId \"FileReadError\" -TargetObject $FilePath\n                            return\n                        }\n                        finally\n                        {\n                            if($stream)\n                            {\n                                $stream.Close()\n                            }\n                        }                            \n                    }\n                }\n            }\n        }\n\n        function Get-DIGSStreamHash\n        {\n            param\n            (\n                [System.IO.Stream]\n                $InputStream,\n\n                [System.String]\n                $RelatedPath,\n\n                [System.Security.Cryptography.HashAlgorithm]\n                $Hasher\n            )\n\n            # Compute file-hash using the crypto object\n            [Byte[]] $computedHash = $Hasher.ComputeHash($InputStream)\n            [string] $hash = [BitConverter]::ToString($computedHash) -replace '-',''\n\n            if ($RelatedPath -eq $null)\n            {\n                $retVal = [PSCustomObject] @{\n                    Algorithm = $Algorithm.ToUpperInvariant()\n                    Hash = $hash\n                }\n                $retVal.psobject.TypeNames.Insert(0, \"Microsoft.Powershell.Utility.FileHash\")\n                $retVal\n            }\n            else\n            {\n                $retVal = [PSCustomObject] @{\n                    Algorithm = $Algorithm.ToUpperInvariant()\n                    Hash = $hash\n                    Path = $RelatedPath\n                }\n                $retVal.psobject.TypeNames.Insert(0, \"Microsoft.Powershell.Utility.FileHash\")\n                $retVal\n\n            }\n        }\n \n        $FileHashCache = @{}\n        $Processes = Get-WmiObject -Class Win32_Process\n\n        function Get-DIGSCachedFileHash\n        {\n            param\n            (\n                [string]\n                $File\n            )\n\n            if($FileHashCache[$File])\n            {\n                $FileHashCache[$File]\n            }\n            else\n            {\n                if($File -and (Test-Path $File))\n                {\n                    $ModuleMD5 = (Get-DIGSFileHash -Path $File -Algorithm MD5).Hash\n                    $ModuleSHA256 = (Get-DIGSFileHash -Path $File -Algorithm SHA256).Hash\n\n                    $FileHashCache[$File] = New-Object PSObject -Property @{\n                        MD5 = $ModuleMD5\n                        SHA256 = $ModuleSHA256\n                    }\n\n                    $FileHashCache[$File]\n                }\n            }\n        }\n    }\n\n    process\n    {\n        foreach($Process in $Processes)\n        {\n            $Proc = Get-Process -Id $Process.ProcessId -ErrorAction SilentlyContinue\n            $Path = $Proc.Path\n            $LoadedModules = $null\n            $Owner = $null\n            $OwnerStr = $null\n\n            if($Proc)\n            {\n                #$PE = Get-PE -ModuleBaseAddress $Proc.MainModule.BaseAddress -ProcessID $Process.ProcessId\n                $Proc.Modules | ForEach-Object {\n                    if($_) \n                    {\n                        $ModuleHash = Get-DIGSCachedFileHash -File $_.FileName\n\n                        $_ | Add-Member NoteProperty -Name \"MD5Hash\" -Value $ModuleHash.MD5\n                        $_ | Add-Member NoteProperty -Name \"SHA256Hash\" -Value $ModuleHash.SHA256\n                    }\n                }\n                $LoadedModules = $Proc.Modules\n            }\n\n            # Get file information\n            $FileHash = $null\n            if($Path -ne $null -and (Test-Path $Path)) {\n                # TODO: Add error handling here in case we can't read the file (wonky exe permissions)\n\n                $FileHash = Get-DIGSCachedFileHash -File $Path\n\n                $File = (Get-ChildItem $Path)\n                $FileSize = $File.Length\n                $FileCreationTime = $File.CreationTimeUtc\n                $FileLastAccessTime = $File.LastAccessTimeUtc\n                $FileLastWriteTime = $File.LastWriteTimeUtc\n                $FileExtension = $File.Extension\n                $ProcessId = $Process.ProcessId\n            } else {\n                if($Proc.Id -ne 0 -and $Proc.Id -ne 4)\n                {\n                    #Write-Warning \"Could not find executable path. PSProcessName: $($Proc.Name) PSPid: $($Proc.Id) WMIProcName: $($Process.Name) WMIPid: $($Process.ProcessId)\"\n                }\n                $Path = ''\n            }\n        \n            # Get the process owner\n            $NTVersion = [System.Environment]::OSVersion.Version\n            try {\n                if($NTVersion.Major -ge 6)\n                {\n                    $Owner = $Process.GetOwner()\n                    if($Owner -and ($Owner.Domain -or $Owner.User)) {\n                        $OwnerStr = \"$($Owner.Domain)\\$($Owner.User)\"\n                    }\n        \n                    $OwnerObj = $Process.GetOwnerSid()\n                    if($OwnerObj)\n                    {\n                        $OwnerSid = $OwnerObj.Sid\n                    }\n                }\n            } catch {}\n\n            $LoadedModuleList = $LoadedModules | sort ModuleName | select -ExpandProperty ModuleName\n            $ParentProcess = Get-Process -Id $Process.ProcessId -ErrorAction SilentlyContinue\n        \n            $ErrorActionPreference = 'Stop'\n            $Output = @{\n                Name = $Process.Name\n                Path = [string]$Process.Path\n                CommandLine = $Process.CommandLine\n                MD5Hash = $FileHash.MD5\n                SHA256Hash = $FileHash.SHA256\n                FileSize = $FileSize\n                FileCreationTime = $FileCreationTime\n                FileLastAccessTime = $FileLastAccessTime\n                FileLastWriteTime = $FileLastWriteTime\n                FileExtension = $FileExtension\n                Owner = $OwnerStr\n                OwnerSid = $OwnerSid\n                ParentProcessId = $Process.ParentProcessID\n                ParentProcessName = $ParentProcess.Name\n                ProcessId = $ProcessId\n                ## PE = $PE\n                #LoadedModules = $LoadedModules | select *\n                LoadedModulesList = ($LoadedModuleList -join \";\").ToLower()\n            }\n\n            try {\n                $null = ConvertTo-JsonV2 $Output\n            } catch {\n                Write-Error $_\n            }\n\n            if($ReturnHashtables) {\n                $Output\n            } else {\n                 New-Object PSObject -Property $Output\n            }\n        }\n    }\n\n    end\n    {\n\n    }\n}\n\nStart-AceScript -Uri https://10.182.18.200 -SweepId $args[0] -ScanId ([Guid]::NewGuid()) -RoutingKey hash.siem -Thumbprint 8D1DB3B7B85B6F9E9DE87B291DF66692A10240AE"
  },
  {
    "path": "ACE-Management/PS-ACE/Scripts/ACE_Get-PSIScheduledTask.ps1",
    "content": "﻿function Start-AceScript\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $SweepId,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $ScanId,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $RoutingKey,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Thumbprint\n    )\n\n    $HostFQDN = Get-WmiObject Win32_ComputerSystem -Property 'Name','Domain' | ForEach-Object {\"$($_.Name).$($_.Domain)\"}\n    $ResultDate = (Get-Date).ToString(\"yyyyMMddThhmmssmsmsZ\")\n\n    $dataList = New-Object -TypeName System.Collections.Generic.List['string']\n\n    foreach($o in (Get-PSIScheduledTask -ReturnHashtables))\n    {\n        $o.Add('ComputerName', $HostFQDN)\n        $o.Add('ScanType', 'ScheduledTask')\n        $o.Add('SweepId', $SweepId)\n        $o.Add('ScanId', $ScanId)\n        $o.Add('ResultDate', $ResultDate)\n\n        $message = ConvertTo-JsonV2 -InputObject $o\n        $dataList.Add($message)\n    }\n\n    $props = @{\n        ComputerName = $HostFQDN\n        ScanType     = 'ScheduledTask'\n        RoutingKey   = $RoutingKey\n        ResultDate   = $ResultDate\n        ScanId       = $ScanId\n        Data         = $dataList.ToArray()\n    }\n\n    $body = (ConvertTo-JsonV2 -InputObject $props)\n\n    Write-Host $body\n\n    Invoke-AceWebRequest -Thumbprint $Thumbprint -Uri \"$($Uri)/ace/result/$($SweepId)\" -Body $body\n}\n\nfunction ConvertTo-JsonV2 \n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        $InputObject\n    )\n\n    Begin \n    {\n        $null = [System.Reflection.Assembly]::LoadWithPartialName(\"System.Web.Extensions\")\n        $Serializer = New-Object System.Web.Script.Serialization.JavaScriptSerializer\n    }\n\n    Process \n    {\n        try \n        {\n            $Serializer.Serialize($InputObject)\n        } \n        catch \n        {\n            Write-Error $_\n        }    \n    }\n}\n\nfunction Invoke-AceWebRequest\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Thumbprint,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Body\n    )\n\n    [Net.ServicePointManager]::ServerCertificateValidationCallback = {\n        $Thumbprint = $Thumbprint\n        $certificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]$args[1]\n    \n        if ($certificate -eq $null)\n        {\n            $Host.UI.WriteErrorLine(\"Null certificate.\")\n            return $true\n        }\n    \n        if ($certificate.Thumbprint -eq $Thumbprint)\n        {\n            return $true\n        }\n        else\n        {\n            $Host.UI.WriteErrorLine(\"Thumbprint mismatch. Certificate thumbprint $($certificate.Thumbprint)\")\n        }\n    \n        return $false\n    }\n\n    try\n    {\n        Write-Host \"URI: $($Uri)\"\n\n        # Create web request\n        $WebRequest = [Net.WebRequest]::Create($uri)\n        $WebRequest.Method = 'Post'\n        $WebRequest.ContentType = 'application/json'\n        $WebRequest.Headers.Add('X-API-Version:1.0')\n\n        $byteArray = [System.Text.Encoding]::UTF8.GetBytes($Body)\n        $Webrequest.ContentLength = $byteArray.Length\n        \n        $dataStream = $Webrequest.GetRequestStream()            \n        $dataStream.Write($byteArray, 0, $byteArray.Length)\n        $dataStream.Close()\n\n        # Get response stream\n        $ResponseStream = $Webrequest.GetResponse().GetResponseStream()\n    \n        # Create a stream reader and read the stream returning the string value.\n        $StreamReader = New-Object System.IO.StreamReader -ArgumentList $ResponseStream\n        $StreamReader.ReadToEnd()\n    }\n    catch\n    {\n        Write-Error \"Failed: $($_.exception.innerexception.message)\"\n    }\n}\n\nfunction Get-PSIScheduledTask {\n<#\n    .SYNOPSIS\n\n        Returns detailed information about scheduled tasks.\n\n        Author: Lee Christensen (@tifkin_), Jared Atkinson\n        License: BSD 3-Clause\n        Required Dependencies: None\n        Optional Dependencies: None\n\n#>\n    [CmdletBinding()]\n    Param (\n        [switch]\n        $ReturnHashtables\n    )\n\n    begin\n    {\n        # Based on Get-ScheduledTask in the Windows 7 Resource Kit PowerShell Pack\n        function Get-DIGSScheduledTaskData\n        {\n        <#\n        .Synopsis\n            Gets tasks scheduled on the computer\n        .Description\n            Gets scheduled tasks that are registered on a computer\n        .Example\n            Get-ScheduleTask -Recurse\n        #>\n        param(\n        # The name or name pattern of the scheduled task\n        [Parameter()]\n        $Name = \"*\",\n    \n        # The folder the scheduled task is in\n        [Parameter()]\n        [String[]]\n        $Folder = \"\",\n    \n        # If this is set, hidden tasks will also be shown.  \n        # By default, only tasks that are not marked by Task Scheduler as hidden are shown.\n        [Switch]\n        $Hidden,    \n    \n        # The name of the computer to connect to.\n        $ComputerName,\n    \n        # The credential used to connect\n        [Management.Automation.PSCredential]\n        $Credential,\n    \n        # If set, will get tasks recursively beneath the specified folder\n        [switch]\n        $Recurse\n        )\n    \n        process {\n            $scheduler = New-Object -ComObject Schedule.Service\n            if ($Credential) { \n                $NetworkCredential = $Credential.GetNetworkCredential()\n                $scheduler.Connect($ComputerName, \n                    $NetworkCredential.UserName, \n                    $NetworkCredential.Domain, \n                    $NetworkCredential.Password)            \n            } else {\n                $scheduler.Connect($ComputerName)        \n            }    \n                \n            $taskFolder = $scheduler.GetFolder($folder)\n            $taskFolder.GetTasks($Hidden -as [bool]) | Where-Object {\n                $_.Name -like $name\n            }\n            if ($Recurse) {\n                $taskFolder.GetFolders(0) | ForEach-Object {\n                    $psBoundParameters.Folder = $_.Path\n                    Get-DIGSScheduledTaskData @psBoundParameters\n                }\n            }        \n        }\n    }\n\n        # Thanks to https://p0w3rsh3ll.wordpress.com/2015/02/05/backporting-the-get-filehash-function/\n        function Get-DIGSFileHash\n        {\n\t    [CmdletBinding(DefaultParameterSetName = \"Path\")]\n\t    param(\n\t\t    [Parameter(Mandatory=$true, ParameterSetName=\"Path\", Position = 0)]\n\t\t    [System.String[]]\n\t\t    $Path,\n\n\t\t    [Parameter(Mandatory=$true, ParameterSetName=\"LiteralPath\", ValueFromPipelineByPropertyName = $true)]\n\t\t    [Alias(\"PSPath\")]\n\t\t    [System.String[]]\n\t\t    $LiteralPath,\n\t\n\t\t    [Parameter(Mandatory=$true, ParameterSetName=\"Stream\")]\n\t\t    [System.IO.Stream]\n\t\t    $InputStream,\n\n\t\t    [ValidateSet(\"SHA1\", \"SHA256\", \"SHA384\", \"SHA512\", \"MACTripleDES\", \"MD5\", \"RIPEMD160\")]\n\t\t    [System.String]\n\t\t    $Algorithm=\"SHA256\"\n\t    )\n\n\t    begin\n\t    {\n\t\t    # Construct the strongly-typed crypto object\n\t\t    $hasher = [System.Security.Cryptography.HashAlgorithm]::Create($Algorithm)\n\t    }\n\n\t    process\n\t    {\n\t\t    if($PSCmdlet.ParameterSetName -eq \"Stream\")\n\t\t    {\n\t\t\t    Get-DIGSStreamHash -InputStream $InputStream -RelatedPath $null -Hasher $hasher\n\t\t    }\n\t\t    else\n\t\t    {\n\t\t\t    $pathsToProcess = @()\n\t\t\t    if($PSCmdlet.ParameterSetName  -eq \"LiteralPath\")\n\t\t\t    {\n\t\t\t\t    $pathsToProcess += Resolve-Path -LiteralPath $LiteralPath | Foreach-Object { $_.ProviderPath }\n\t\t\t    }\n\t\t\t    if($PSCmdlet.ParameterSetName -eq \"Path\")\n\t\t\t    {\n\t\t\t\t    $pathsToProcess += Resolve-Path $Path | Foreach-Object { $_.ProviderPath }\n\t\t\t    }\n\n\t\t\t    foreach($filePath in $pathsToProcess)\n\t\t\t    {\n\t\t\t\t    if(Test-Path -LiteralPath $filePath -PathType Container)\n\t\t\t\t    {\n\t\t\t\t\t    continue\n\t\t\t\t    }\n\n\t\t\t\t    try\n\t\t\t\t    {\n\t\t\t\t\t    # Read the file specified in $FilePath as a Byte array\n\t\t\t\t\t    [system.io.stream]$stream = [system.io.file]::OpenRead($filePath)\n\t\t\t\t\t    Get-DIGSStreamHash -InputStream $stream  -RelatedPath $filePath -Hasher $hasher\n\t\t\t\t    }\n\t\t\t\t    catch [Exception]\n\t\t\t\t    {\n\t\t\t\t\t    $errorMessage = 'FileReadError {0}:{1}' -f $FilePath, $_\n\t\t\t\t\t    Write-Error -Message $errorMessage -Category ReadError -ErrorId \"FileReadError\" -TargetObject $FilePath\n\t\t\t\t\t    return\n\t\t\t\t    }\n\t\t\t\t    finally\n\t\t\t\t    {\n\t\t\t\t\t    if($stream)\n\t\t\t\t\t    {\n\t\t\t\t\t\t    $stream.Close()\n\t\t\t\t\t    }\n\t\t\t\t    }                            \n\t\t\t    }\n\t\t    }\n\t    }\n    }\n\n        function Get-DIGSStreamHash\n        {\n\t    param(\n\t\t    [System.IO.Stream]\n\t\t    $InputStream,\n\n\t\t    [System.String]\n\t\t    $RelatedPath,\n\n\t\t    [System.Security.Cryptography.HashAlgorithm]\n\t\t    $Hasher)\n\n\t    # Compute file-hash using the crypto object\n\t    [Byte[]] $computedHash = $Hasher.ComputeHash($InputStream)\n\t    [string] $hash = [BitConverter]::ToString($computedHash) -replace '-',''\n\n\t    if ($RelatedPath -eq $null)\n\t    {\n\t\t    $retVal = [PSCustomObject] @{\n\t\t\t    Algorithm = $Algorithm.ToUpperInvariant()\n\t\t\t    Hash = $hash\n\t\t    }\n\t\t    $retVal.psobject.TypeNames.Insert(0, \"Microsoft.Powershell.Utility.FileHash\")\n\t\t    $retVal\n\t    }\n\t    else\n\t    {\n\t\t    $retVal = [PSCustomObject] @{\n\t\t\t    Algorithm = $Algorithm.ToUpperInvariant()\n\t\t\t    Hash = $hash\n\t\t\t    Path = $RelatedPath\n\t\t    }\n\t\t    $retVal.psobject.TypeNames.Insert(0, \"Microsoft.Powershell.Utility.FileHash\")\n\t\t    $retVal\n\n\t    }\n    }\n\n        function Get-ClassID\n        {\n            param($ClassId)\n  \n            $Value = Get-ItemProperty \"HKLM:\\Software\\Classes\\CLSID\\$($ClassId)\\InprocServer32\" -Name \"(Default)\" -ErrorAction SilentlyContinue\n            if($Value) {\n                $Value.'(Default)'\n            } else {\n                ''\n            }\n        }  \n    }\n\n    process\n    {\n        $Tasks = Get-DIGSScheduledTaskData -Recurse\n\n        foreach($Task in $Tasks)\n        {\n            $ActionComClassId = $null\n            $ActionComDll = $null\n            $ActionComDllMD5 = $null\n            $ActionComDllSHA256 = $null\n            $ActionComData = $null\n            $ActionExecCommand = $null\n            $ActionExecCommandMD5 = $null\n            $ActionExecCommandSHA256 = $null\n            $ActionExecArguments = $null\n            $ActionExecWorkingDirectory = $null\n                \n            $Xml = [Xml]$Task.Xml\n    \n            $ActionCom = $Xml.Task.Actions.ComHandler\n            $ActionComDll = if($ActionCom.ClassId) { Get-ClassID ($ActionCom.ClassId)} else { $null }\n        \n            if($ActionComDll)\n            {\n                $ActionComDllMD5 =  (Get-DIGSFileHash -Path $ActionComDll -Algorithm MD5).Hash\n                $ActionComDllSHA256 = (Get-DIGSFileHash -Path $ActionComDll -Algorithm SHA256).Hash\n            }\n            $ActionComData = if($ActionCom.Data) { $ActionCom.Data.InnerXml} else {$null}\n\n            $ActionExec = $Xml.Task.Actions.Exec\n            if($ActionExec.Command)\n            {\n                $ActionExecPath = [System.Environment]::ExpandEnvironmentVariables($ActionExec.Command)\n            \n                $CleanedPath = $ActionExecPath.Replace(\"`\"\", \"\")\n                if(Test-Path $CleanedPath -ErrorAction SilentlyContinue)\n                {\n                    $ActionExecCommandMD5 = (Get-DIGSFileHash -Path $CleanedPath -Algorithm MD5).Hash\n                    $ActionExecCommandSHA256 = (Get-DIGSFileHash -Path $CleanedPath -Algorithm SHA256).Hash\n                }\n            }\n\n            $Output = @{\n                Name = $Task.Name\n                Path = $Task.Path\n                Enabled = $Task.Enabled\n                LastRunTime = $Task.LastRunTime\n                LastTaskResult = $Task.LastTaskResult\n                NumberOfMissedRuns = $Task.NumberOfMissedRuns\n                NextRunTime = $Task.NextRunTime\n                Xml = $Task.Xml\n                ActionComClassId = $ActionCom.ClassId\n                ActionComDll = $ActionComDll\n                ActionComDllMD5 = $ActionComDllMd5\n                ActionComDllSHA256 = $ActionComDllSHA256\n                ActionComData = $ActionComData\n                ActionExecCommand = $ActionExec.Command\n                ActionExecCommandMD5 = $ActionExecCommandMD5\n                ActionExecCommandSHA256 = $ActionExecCommandSHA256\n                ActionExecArguments = $ActionExec.Arguments\n                ActionExecWorkingDirectory = $ActionExec.WorkingDirectory\n            }\n\n            if($ReturnHashtables) {\n                $Output\n            } else {\n                New-Object PSObject -Property $Output\n            }\n        }\n    }\n\n    end\n    {\n\n    }\n}\n\nStart-AceScript -Uri https://10.182.18.200 -SweepId $args[0] -ScanId ([Guid]::NewGuid()) -RoutingKey siem -Thumbprint 8D1DB3B7B85B6F9E9DE87B291DF66692A10240AE"
  },
  {
    "path": "ACE-Management/PS-ACE/Scripts/ACE_Get-PSIService.ps1",
    "content": "﻿function Start-AceScript\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $SweepId,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $ScanId,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $RoutingKey,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Thumbprint\n    )\n\n    $HostFQDN = Get-WmiObject Win32_ComputerSystem -Property 'Name','Domain' | ForEach-Object {\"$($_.Name).$($_.Domain)\"}\n    $ResultDate = (Get-Date).ToString(\"yyyyMMddThhmmssmsmsZ\")\n\n    $dataList = New-Object -TypeName System.Collections.Generic.List['string']\n\n    foreach($o in (Get-PSIService -ReturnHashtables))\n    {\n        $o.Add('ComputerName', $HostFQDN)\n        $o.Add('ScanType', 'Service')\n        $o.Add('SweepId', $SweepId)\n        $o.Add('ScanId', $ScanId)\n        $o.Add('ResultDate', $ResultDate)\n\n        $message = ConvertTo-JsonV2 -InputObject $o\n        $dataList.Add($message)\n    }\n\n    $props = @{\n        ComputerName = $HostFQDN\n        ScanType     = 'Service'\n        RoutingKey   = $RoutingKey\n        ResultDate   = $ResultDate\n        ScanId       = $ScanId\n        Data         = $dataList.ToArray()\n    }\n\n    $body = (ConvertTo-JsonV2 -InputObject $props)\n\n    Write-Host $body\n\n    Invoke-AceWebRequest -Thumbprint $Thumbprint -Uri \"$($Uri)/ace/result/$($SweepId)\" -Body $body\n}\n\nfunction ConvertTo-JsonV2 \n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        $InputObject\n    )\n\n    Begin \n    {\n        $null = [System.Reflection.Assembly]::LoadWithPartialName(\"System.Web.Extensions\")\n        $Serializer = New-Object System.Web.Script.Serialization.JavaScriptSerializer\n    }\n\n    Process \n    {\n        try \n        {\n            $Serializer.Serialize($InputObject)\n        } \n        catch \n        {\n            Write-Error $_\n        }    \n    }\n}\n\nfunction Invoke-AceWebRequest\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Thumbprint,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Body\n    )\n\n    [Net.ServicePointManager]::ServerCertificateValidationCallback = {\n        $Thumbprint = $Thumbprint\n        $certificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]$args[1]\n    \n        if ($certificate -eq $null)\n        {\n            $Host.UI.WriteErrorLine(\"Null certificate.\")\n            return $true\n        }\n    \n        if ($certificate.Thumbprint -eq $Thumbprint)\n        {\n            return $true\n        }\n        else\n        {\n            $Host.UI.WriteErrorLine(\"Thumbprint mismatch. Certificate thumbprint $($certificate.Thumbprint)\")\n        }\n    \n        return $false\n    }\n\n    try\n    {\n        Write-Host \"URI: $($Uri)\"\n\n        # Create web request\n        $WebRequest = [Net.WebRequest]::Create($uri)\n        $WebRequest.Method = 'Post'\n        $WebRequest.ContentType = 'application/json'\n        $WebRequest.Headers.Add('X-API-Version:1.0')\n\n        $byteArray = [System.Text.Encoding]::UTF8.GetBytes($Body)\n        $Webrequest.ContentLength = $byteArray.Length\n        \n        $dataStream = $Webrequest.GetRequestStream()            \n        $dataStream.Write($byteArray, 0, $byteArray.Length)\n        $dataStream.Close()\n\n        # Get response stream\n        $ResponseStream = $Webrequest.GetResponse().GetResponseStream()\n    \n        # Create a stream reader and read the stream returning the string value.\n        $StreamReader = New-Object System.IO.StreamReader -ArgumentList $ResponseStream\n        $StreamReader.ReadToEnd()\n    }\n    catch\n    {\n        Write-Error \"Failed: $($_.exception.innerexception.message)\"\n    }\n}\n\nfunction Get-PSIService \n{\n<#\n    .SYNOPSIS\n\n        Returns detailed service information.\n\n        Author: Jared Atkinson\n        License: BSD 3-Clause\n        Required Dependencies: None\n        Optional Dependencies: None\n\n#>\n    [CmdletBinding()]\n    Param (\n        [switch]\n        $ReturnHashtables\n    )\n\n    Begin\n    {\n        function Get-PathFromCommandLine\n        {\n            Param\n            (\n                [Parameter(Mandatory = $true)]\n                [string]\n                $CommandLine\n            )\n\n            if(Test-Path -Path $CommandLine -ErrorAction SilentlyContinue)\n            {\n                $CommandLine\n            }\n            else\n            {\n                switch -Regex ($CommandLine)\n                {\n                    '\"\\s'{ $CommandLine.Split('\"')[1]; break}\n                    '\\s-'{ $CommandLine.Split(' ')[0]; break}\n                    '\\s/'{ $CommandLine.Split(' ')[0]; break}\n                    '\"'{ $CommandLine.Split('\"')[1]; break}\n                    default{ $CommandLine}    \n                }\n            }\n        }\n\n        # Thanks to https://p0w3rsh3ll.wordpress.com/2015/02/05/backporting-the-get-filehash-function/\n        function Get-DIGSFileHash\n        {\n            [CmdletBinding(DefaultParameterSetName = \"Path\")]\n            param(\n                [Parameter(Mandatory=$true, ParameterSetName=\"Path\", Position = 0)]\n                [System.String[]]\n                $Path,\n\n                [Parameter(Mandatory=$true, ParameterSetName=\"LiteralPath\", ValueFromPipelineByPropertyName = $true)]\n                [Alias(\"PSPath\")]\n                [System.String[]]\n                $LiteralPath,\n        \n                [Parameter(Mandatory=$true, ParameterSetName=\"Stream\")]\n                [System.IO.Stream]\n                $InputStream,\n\n                [ValidateSet(\"SHA1\", \"SHA256\", \"SHA384\", \"SHA512\", \"MACTripleDES\", \"MD5\", \"RIPEMD160\")]\n                [System.String]\n                $Algorithm=\"SHA256\"\n            )\n    \n            begin\n            {\n                # Construct the strongly-typed crypto object\n                $hasher = [System.Security.Cryptography.HashAlgorithm]::Create($Algorithm)\n            }\n    \n            process\n            {\n                if($PSCmdlet.ParameterSetName -eq \"Stream\")\n                {\n                    Get-DIGSStreamHash -InputStream $InputStream -RelatedPath $null -Hasher $hasher\n                }\n                else\n                {\n                    $pathsToProcess = @()\n                    if($PSCmdlet.ParameterSetName  -eq \"LiteralPath\")\n                    {\n                        $pathsToProcess += Resolve-Path -LiteralPath $LiteralPath | Foreach-Object { $_.ProviderPath }\n                    }\n                    if($PSCmdlet.ParameterSetName -eq \"Path\")\n                    {\n                        $pathsToProcess += Resolve-Path $Path | Foreach-Object { $_.ProviderPath }\n                    }\n\n                    foreach($filePath in $pathsToProcess)\n                    {\n                        if(Test-Path -LiteralPath $filePath -PathType Container)\n                        {\n                            continue\n                        }\n\n                        try\n                        {\n                            # Read the file specified in $FilePath as a Byte array\n                            [system.io.stream]$stream = [system.io.file]::OpenRead($filePath)\n                            Get-DIGSStreamHash -InputStream $stream  -RelatedPath $filePath -Hasher $hasher\n                        }\n                        catch [Exception]\n                        {\n                            $errorMessage = 'FileReadError {0}:{1}' -f $FilePath, $_\n                            Write-Error -Message $errorMessage -Category ReadError -ErrorId \"FileReadError\" -TargetObject $FilePath\n                            return\n                        }\n                        finally\n                        {\n                            if($stream)\n                            {\n                                $stream.Close()\n                            }\n                        }                            \n                    }\n                }\n            }\n        }\n\n        function Get-DIGSStreamHash\n        {\n            param(\n                [System.IO.Stream]\n                $InputStream,\n\n                [System.String]\n                $RelatedPath,\n\n                [System.Security.Cryptography.HashAlgorithm]\n                $Hasher)\n\n            # Compute file-hash using the crypto object\n            [Byte[]] $computedHash = $Hasher.ComputeHash($InputStream)\n            [string] $hash = [BitConverter]::ToString($computedHash) -replace '-',''\n\n            if ($RelatedPath -eq $null)\n            {\n                $retVal = [PSCustomObject] @{\n                    Algorithm = $Algorithm.ToUpperInvariant()\n                    Hash = $hash\n                }\n                $retVal.psobject.TypeNames.Insert(0, \"Microsoft.Powershell.Utility.FileHash\")\n                $retVal\n            }\n            else\n            {\n                $retVal = [PSCustomObject] @{\n                    Algorithm = $Algorithm.ToUpperInvariant()\n                    Hash = $hash\n                    Path = $RelatedPath\n                }\n                $retVal.psobject.TypeNames.Insert(0, \"Microsoft.Powershell.Utility.FileHash\")\n                $retVal\n\n            }\n        }\n    \n        $hashcache = @{}\n        $objList = New-Object -TypeName \"System.Collections.Generic.List[Object]\"\n    }\n\n    Process\n    {\n        foreach($service in (Get-WmiObject win32_service))\n        {\n            if($service.PathName -ne $null)\n            {\n                $path = Get-PathFromCommandLine -CommandLine $service.PathName\n            }\n            else\n            {\n                $path = $null\n            }\n\n            try\n            {\n                if($hashcache.ContainsKey($path))\n                {\n                    $md5 = $hashcache[$path].MD5\n                    $sha256 = $hashcache[$path].SHA256\n                }\n                else\n                {\n                    $md5 = Get-DIGSFileHash -Path $path -Algorithm MD5 -ErrorAction Stop\n                    $sha256 = Get-DIGSFileHash -Path $path -Algorithm SHA256 -ErrorAction Stop\n                    $obj = @{\n                        MD5 = $md5\n                        SHA256 = $sha256\n                    }\n                    $hashcache.Add($path, $obj)\n                }\n            }\n            catch\n            {\n                $md5 = $null\n                $sha256 = $null\n            }\n        \n            $Props = @{\n                Name = $service.Name\n                CommandLine = $service.PathName\n                ExecutablePath = $path\n                ServiceType = $service.ServiceType\n                StartMode = $service.StartMode\n                Caption = $service.Caption\n                Description = $service.Description\n                DisplayName = $service.DisplayName\n                ProcessId = $service.ProcessId\n                Started = $service.Started\n                User = $service.StartName\n                MD5Hash = $md5.Hash\n                SHA256Hash = $sha256.Hash\n            }\n\n            if($ReturnHashtables) {\n                $Props\n            } else {\n                New-Object -TypeName psobject -Property $Props\n            }\n        }\n    }\n\n    End\n    {\n\n    }\n}\n\nStart-AceScript -Uri https://10.182.18.200 -SweepId $args[0] -ScanId ([Guid]::NewGuid()) -RoutingKey siem -Thumbprint 8D1DB3B7B85B6F9E9DE87B291DF66692A10240AE"
  },
  {
    "path": "ACE-Management/PS-ACE/Scripts/ACE_Get-PSIWindowsSecurityEvent.ps1",
    "content": "﻿function Start-AceScript\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $SweepId,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $ScanId,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $RoutingKey,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Thumbprint\n    )\n\n    $HostFQDN = Get-WmiObject Win32_ComputerSystem -Property 'Name','Domain' | ForEach-Object {\"$($_.Name).$($_.Domain)\"}\n    $ResultDate = (Get-Date).ToString(\"yyyyMMddThhmmssmsmsZ\")\n\n    $dataList = New-Object -TypeName System.Collections.Generic.List['string']\n\n    foreach($o in (Get-PSIWindowsSecurityEvent -ReturnHashtables))\n    {\n        $o.Add('ComputerName', $HostFQDN)\n        $o.Add('ScanType', 'WindowsSecurityEvent')\n        $o.Add('SweepId', $SweepId)\n        $o.Add('ScanId', $ScanId)\n        $o.Add('ResultDate', $ResultDate)\n\n        $message = ConvertTo-JsonV2 -InputObject $o\n        $dataList.Add($message)\n    }\n\n    $props = @{\n        ComputerName = $HostFQDN\n        ScanType     = 'WindowsSecurityEvent'\n        RoutingKey   = $RoutingKey\n        ResultDate   = $ResultDate\n        ScanId       = $ScanId\n        Data         = $dataList.ToArray()\n    }\n\n    $body = (ConvertTo-JsonV2 -InputObject $props)\n\n    Write-Host $body\n\n    Invoke-AceWebRequest -Thumbprint $Thumbprint -Uri \"$($Uri)/ace/result/$($SweepId)\" -Body $body\n}\n\nfunction ConvertTo-JsonV2 \n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        $InputObject\n    )\n\n    Begin \n    {\n        $null = [System.Reflection.Assembly]::LoadWithPartialName(\"System.Web.Extensions\")\n        $Serializer = New-Object System.Web.Script.Serialization.JavaScriptSerializer\n    }\n\n    Process \n    {\n        try \n        {\n            $Serializer.Serialize($InputObject)\n        } \n        catch \n        {\n            Write-Error $_\n        }    \n    }\n}\n\nfunction Invoke-AceWebRequest\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Thumbprint,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Body\n    )\n\n    [Net.ServicePointManager]::ServerCertificateValidationCallback = {\n        $Thumbprint = $Thumbprint\n        $certificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]$args[1]\n    \n        if ($certificate -eq $null)\n        {\n            $Host.UI.WriteErrorLine(\"Null certificate.\")\n            return $true\n        }\n    \n        if ($certificate.Thumbprint -eq $Thumbprint)\n        {\n            return $true\n        }\n        else\n        {\n            $Host.UI.WriteErrorLine(\"Thumbprint mismatch. Certificate thumbprint $($certificate.Thumbprint)\")\n        }\n    \n        return $false\n    }\n\n    try\n    {\n        Write-Host \"URI: $($Uri)\"\n\n        # Create web request\n        $WebRequest = [Net.WebRequest]::Create($uri)\n        $WebRequest.Method = 'Post'\n        $WebRequest.ContentType = 'application/json'\n        $WebRequest.Headers.Add('X-API-Version:1.0')\n\n        $byteArray = [System.Text.Encoding]::UTF8.GetBytes($Body)\n        $Webrequest.ContentLength = $byteArray.Length\n        \n        $dataStream = $Webrequest.GetRequestStream()            \n        $dataStream.Write($byteArray, 0, $byteArray.Length)\n        $dataStream.Close()\n\n        # Get response stream\n        $ResponseStream = $Webrequest.GetResponse().GetResponseStream()\n    \n        # Create a stream reader and read the stream returning the string value.\n        $StreamReader = New-Object System.IO.StreamReader -ArgumentList $ResponseStream\n        $StreamReader.ReadToEnd()\n    }\n    catch\n    {\n        Write-Error \"Failed: $($_.exception.innerexception.message)\"\n    }\n}\n\nfunction Get-PSIWindowsSecurityEvent {\n<#\n    .SYNOPSIS\n\n        Returns detailed Security Event information\n\n        Author: Lee Christensen (@tifkin_)\n        License: BSD 3-Clause\n        Required Dependencies: None\n        Optional Dependencies: None\n\n#>\n    Param\n    (\n        [Parameter(Mandatory=$false,\n                    ValueFromPipelineByPropertyName=$true,\n                    Position=0)]\n        $StartTime = [DateTime]::Now.AddDays(-1),\n\n        [Parameter(Mandatory=$false,\n            ValueFromPipelineByPropertyName=$true,\n            Position=1)]\n        $EndTime = [DateTime]::Now,\n\n        [switch]\n        $ReturnHashtables\n    )\n\n    Begin\n    {\n        <# *** TODO ***\n        - service added/deleted/started\n        - Process logging... Maybe only log interesting processes that are executed instead of grabbing all processes?\n        - Scheduled Task creations/deletions. Runs? (Applications Services Logs\\Microsoft\\Windows\\TaskScheduler)\n        - Remote Desktop Connections (Applications Services Logs\\Microsoft\\Windows\\TerminalServices-RemoteConnectionManager\\Operational - EID 1149).  Note this does not indicate a login. It only indicates a connection\n        - Remote Desktop Logons/Disconnections (Applications Services Logs\\Microsoft\\Windows\\TerminalServices-LocalSessionManager\\Operational - EID 21,24).  This isn't very chatty, so you could probably pull them all.\n        - Symantec Enpoint Protection Client log\n        - BITS Transfers (Applications Services Logs\\Microsoft\\Windows\\Bits-Client  EID 59).  Historically used to exfil data/persistence\n        #>\n\n        $XPathFilter = @\"\n<QueryList>\n    <Query Id=\"0\" Path=\"Security\">\n\n        <!-- Logon events -->\n        <Select Path=\"Security\">\n            *[\n                System[\n                    Provider[\n                        @Name='Microsoft-Windows-Security-Auditing'\n                    ]\n                    and (Level=4 or Level=0) and (EventID=4624)\n                    and TimeCreated[\n\t\t\t\t\t    @SystemTime&gt;='$($StartTime.ToUniversalTime().ToString('s'))' and @SystemTime&lt;='$($EndTime.ToUniversalTime().ToString('s'))'\n\t\t\t\t    ]\n                ]\n            ]\n            and\n            *[EventData[Data[@Name='TargetUserName'] != 'ANONYMOUS LOGON']]\n        </Select>\n\n        <!-- Logon with explicit credential events -->\n        <Select Path=\"Security\">\n            *[\n                System[\n                    Provider[\n                        @Name='Microsoft-Windows-Security-Auditing'\n                    ]\n                    and (Level=4 or Level=0) and (EventID=4648)\n                    and TimeCreated[\n\t\t\t\t\t    @SystemTime&gt;='$($StartTime.ToUniversalTime().ToString('s'))' and @SystemTime&lt;='$($EndTime.ToUniversalTime().ToString('s'))'\n\t\t\t\t    ]\n                ]\n            ]\n        </Select>\n\n        <!-- RDP logon events -->\n        <Select Path=\"Security\">\n            *[\n                System[\n                    Provider[\n                        @Name='Microsoft-Windows-Security-Auditing'\n                    ] \n                    and \n                    (Level=4 or Level=0) and (EventID=4624 or EventID=4634)\n                    and \n                    TimeCreated[\n\t\t\t\t\t    @SystemTime&gt;='$($StartTime.ToUniversalTime().ToString('s'))' and @SystemTime&lt;='$($EndTime.ToUniversalTime().ToString('s'))'\n\t\t\t\t    ]\n                ]\n            ]\n            and\n            *[EventData[Data[@Name='LogonType']='10']]\n            and\n            (\n                *[EventData[Data[5]='10']]\n                or\n                *[EventData[Data[@Name='AuthenticationPackageName']='Negotiate']]\n            )\n        </Select>\n\n        <!-- Local user created or deleted -->\n        <Select Path=\"Security\">\n            *[\n                System[\n                    (EventID=4726 or EventID=4720)\n                    and \n                    TimeCreated[\n\t\t\t\t\t    @SystemTime&gt;='$($StartTime.ToUniversalTime().ToString('s'))' and @SystemTime&lt;='$($EndTime.ToUniversalTime().ToString('s'))'\n\t\t\t\t    ]\n                ]\n            ]\n        </Select>\n\n        <!-- Local admins changed -->\n        <Select Path=\"Security\">\n            *[\n                System[\n                    (EventID=4732 or EventID=4733)\n                    and \n                    TimeCreated[\n\t\t\t\t\t    @SystemTime&gt;='$($StartTime.ToUniversalTime().ToString('s'))' and @SystemTime&lt;='$($EndTime.ToUniversalTime().ToString('s'))'\n\t\t\t\t    ]\n                ]\n            ]\n            and\n            *[EventData[Data[@Name='TargetUserName']='Administrators']]\n        </Select>\n\n        <!-- Event log cleared -->\n        <Select Path=\"Security\">\n            *[\n                System[\n                    (EventID=1102)\n                    and\n                    TimeCreated[\n\t\t\t\t\t    @SystemTime&gt;='$($StartTime.ToUniversalTime().ToString('s'))' and @SystemTime&lt;='$($EndTime.ToUniversalTime().ToString('s'))'\n\t\t\t\t    ]\n                ]\n            ]\n        </Select>\n\n        <Suppress Path=\"Security\">\n            *[\n                System[\n                    Provider[\n                        @Name='Microsoft-Windows-Security-Auditing'\n                    ]\n                    and\n                    (Level=4 or Level=0) and (EventID=4624 or EventID=4625 or EventID=4634)\n                ]\n            ]\n            and\n            *[\n                EventData[\n                    (\n                        (Data[@Name='LogonType']='5' or Data[@Name='LogonType']='0') \n                        or\n                        Data[@Name='TargetUserName']='ANONYMOUS LOGON'\n                        or\n                        Data[@Name='TargetUserSID']='S-1-5-18'\n                    )\n                ]\n            ]\n        </Suppress>\n    </Query>\n</QueryList>\n\"@\n  \n        function Convert-SidToName {\n        <#\n            .SYNOPSIS\n    \n                Converts a security identifier (SID) to a group/user name. Graciously taken from @harmj0y's PowerView project.\n\n            .PARAMETER SID\n    \n                The SID to convert.\n\n            .EXAMPLE\n\n                PS C:\\> Convert-SidToName S-1-5-21-2620891829-2411261497-1773853088-1105\n        #>\n            [CmdletBinding()]\n            param(\n                [Parameter(Mandatory=$True,ValueFromPipeline=$True)]\n                [String]\n                $SID\n            )\n\n            process {\n                try {\n                    $SID2 = $SID.trim('*')\n\n                    # try to resolve any built-in SIDs first\n                    #   from https://support.microsoft.com/en-us/kb/243330\n                    Switch ($SID2)\n                    {\n                        'S-1-0'         { 'Null Authority' }\n                        'S-1-0-0'       { 'Nobody' }\n                        'S-1-1'         { 'World Authority' }\n                        'S-1-1-0'       { 'Everyone' }\n                        'S-1-2'         { 'Local Authority' }\n                        'S-1-2-0'       { 'Local' }\n                        'S-1-2-1'       { 'Console Logon ' }\n                        'S-1-3'         { 'Creator Authority' }\n                        'S-1-3-0'       { 'Creator Owner' }\n                        'S-1-3-1'       { 'Creator Group' }\n                        'S-1-3-2'       { 'Creator Owner Server' }\n                        'S-1-3-3'       { 'Creator Group Server' }\n                        'S-1-3-4'       { 'Owner Rights' }\n                        'S-1-4'         { 'Non-unique Authority' }\n                        'S-1-5'         { 'NT Authority' }\n                        'S-1-5-1'       { 'Dialup' }\n                        'S-1-5-2'       { 'Network' }\n                        'S-1-5-3'       { 'Batch' }\n                        'S-1-5-4'       { 'Interactive' }\n                        'S-1-5-6'       { 'Service' }\n                        'S-1-5-7'       { 'Anonymous' }\n                        'S-1-5-8'       { 'Proxy' }\n                        'S-1-5-9'       { 'Enterprise Domain Controllers' }\n                        'S-1-5-10'      { 'Principal Self' }\n                        'S-1-5-11'      { 'Authenticated Users' }\n                        'S-1-5-12'      { 'Restricted Code' }\n                        'S-1-5-13'      { 'Terminal Server Users' }\n                        'S-1-5-14'      { 'Remote Interactive Logon' }\n                        'S-1-5-15'      { 'This Organization ' }\n                        'S-1-5-17'      { 'This Organization ' }\n                        'S-1-5-18'      { 'Local System' }\n                        'S-1-5-19'      { 'NT Authority' }\n                        'S-1-5-20'      { 'NT Authority' }\n                        'S-1-5-80-0'    { 'All Services ' }\n                        'S-1-5-32-544'  { 'BUILTIN\\Administrators' }\n                        'S-1-5-32-545'  { 'BUILTIN\\Users' }\n                        'S-1-5-32-546'  { 'BUILTIN\\Guests' }\n                        'S-1-5-32-547'  { 'BUILTIN\\Power Users' }\n                        'S-1-5-32-548'  { 'BUILTIN\\Account Operators' }\n                        'S-1-5-32-549'  { 'BUILTIN\\Server Operators' }\n                        'S-1-5-32-550'  { 'BUILTIN\\Print Operators' }\n                        'S-1-5-32-551'  { 'BUILTIN\\Backup Operators' }\n                        'S-1-5-32-552'  { 'BUILTIN\\Replicators' }\n                        'S-1-5-32-554'  { 'BUILTIN\\Pre-Windows 2000 Compatible Access' }\n                        'S-1-5-32-555'  { 'BUILTIN\\Remote Desktop Users' }\n                        'S-1-5-32-556'  { 'BUILTIN\\Network Configuration Operators' }\n                        'S-1-5-32-557'  { 'BUILTIN\\Incoming Forest Trust Builders' }\n                        'S-1-5-32-558'  { 'BUILTIN\\Performance Monitor Users' }\n                        'S-1-5-32-559'  { 'BUILTIN\\Performance Log Users' }\n                        'S-1-5-32-560'  { 'BUILTIN\\Windows Authorization Access Group' }\n                        'S-1-5-32-561'  { 'BUILTIN\\Terminal Server License Servers' }\n                        'S-1-5-32-562'  { 'BUILTIN\\Distributed COM Users' }\n                        'S-1-5-32-569'  { 'BUILTIN\\Cryptographic Operators' }\n                        'S-1-5-32-573'  { 'BUILTIN\\Event Log Readers' }\n                        'S-1-5-32-574'  { 'BUILTIN\\Certificate Service DCOM Access' }\n                        'S-1-5-32-575'  { 'BUILTIN\\RDS Remote Access Servers' }\n                        'S-1-5-32-576'  { 'BUILTIN\\RDS Endpoint Servers' }\n                        'S-1-5-32-577'  { 'BUILTIN\\RDS Management Servers' }\n                        'S-1-5-32-578'  { 'BUILTIN\\Hyper-V Administrators' }\n                        'S-1-5-32-579'  { 'BUILTIN\\Access Control Assistance Operators' }\n                        'S-1-5-32-580'  { 'BUILTIN\\Access Control Assistance Operators' }\n                        Default { \n                            $Obj = (New-Object System.Security.Principal.SecurityIdentifier($SID2))\n                            $Obj.Translate( [System.Security.Principal.NTAccount]).Value\n                        }\n                    }\n                }\n                catch {\n                    # Write-Warning \"Invalid SID: $SID\"\n                    $SID\n                }\n            }\n        }\n    }\n\n    Process\n    {\n        Get-WinEvent -FilterXPath $XPathFilter -LogName Security -MaxEvents 3000 | ForEach-Object {\n            $Event = $null\n            $Properties = $null\n            $Output = $null\n\n            $Event = $_\n            $Properties = $Event.Properties\n            switch($Event.Id)\n            {\n                # Event log cleared\n                1102\n                {\n                    $Output = @{\n                        TimeCreated       = $Event.TimeCreated\n                        EventId           = $Event.Id\n                        SubjectUserSid    = $Properties[0].Value.ToString()\n                        SubjectUserName   = $Properties[1].Value\n                        SubjectDomainName = $Properties[2].Value\n                        SubjectLogonId    = $Properties[3].Value\n                    }\n\n                    if(-not $ReturnHashtables) {\n                        $Output = New-Object PSObject -Property $Output\n                        $Output.PSObject.TypeNames.Insert(0, 'LogClearedEvent')\n                    }\n\n                    break\n                }\n\n                # Logon event\n                4624 \n                {\n                    $Output = @{\n                        TimeCreated               = $Event.TimeCreated\n                        EventId                   = $Event.Id\n                        SubjectUserSid            = $Properties[0].Value.ToString()\n                        SubjectUserName           = $Properties[1].Value\n                        SubjectDomainName         = $Properties[2].Value\n                        SubjectLogonId            = $Properties[3].Value\n                        TargetUserSid             = $Properties[4].Value.ToString()\n                        TargetUserName            = $Properties[5].Value\n                        TargetDomainName          = $Properties[6].Value\n                        TargetLogonId             = $Properties[7].Value\n                        LogonType                 = $Properties[8].Value\n                        LogonProcessName          = $Properties[9].Value\n                        AuthenticationPackageName = $Properties[10].Value\n                        WorkstationName           = $Properties[11].Value\n                        LogonGuid                 = $Properties[12].Value\n                        TransmittedServices       = $Properties[13].Value\n                        LmPackageName             = $Properties[14].Value\n                        KeyLength                 = $Properties[15].Value\n                        ProcessId                 = $Properties[16].Value\n                        ProcessName               = $Properties[17].Value\n                        IpAddress                 = $Properties[18].Value\n                        IpPort                    = $Properties[19].Value\n                        ImpersonationLevel        = $Properties[20].Value\n                        RestrictedAdminMode       = $Properties[21].Value\n                        TargetOutboundUserName    = $Properties[22].Value\n                        TargetOutboundDomainName  = $Properties[23].Value\n                        VirtualAccount            = $Properties[24].Value\n                        TargetLinkedLogonId       = $Properties[25].Value\n                        ElevatedToken             = $Properties[26].Value\n                    }\n\n                    if(-not $ReturnHashtables) {\n                        $Output = New-Object PSObject -Property $Output\n                        $Output.PSObject.TypeNames.Insert(0, 'LogonEvent')\n                    }\n\n                    break\n                }\n\n                # RDP Logoff event\n                4634 \n                {\n                    $Output = @{\n                        TimeCreated      = $Event.TimeCreated\n                        EventId          = $Event.Id\n                        TargetUserSid    = $Properties[0].Value.ToString()\n                        TargetUserName   = $Properties[1].Value\n                        TargetDomainName = $Properties[2].Value\n                        TargetLogonId    = $Properties[3].Value\n                        LogonType        = $Properties[4].Value.ToString()\n                    }\n\n                    if(-not $ReturnHashtables) {\n                        $Output = New-Object PSObject -Property $Output\n                        $Output.PSObject.TypeNames.Insert(0, 'LogoffEvent')\n                    }\n\n                    break\n                }\n\n                # Logon with explicit credential\n                4648 \n                {\n                    # Skip computer logons for now\n                    # TODO: Can this be used for silver ticket detection?\n                    if(!($Properties[5].Value.EndsWith('$') -and $Properties[11].Value -match 'taskhost\\.exe'))\n                    {\n                        $Output = @{\n                            TimeCreated       = $Event.TimeCreated\n                            EventId           = $Event.Id\n                            SubjectUserSid    = $Properties[0].Value.ToString()\n                            SubjectUserName   = $Properties[1].Value\n                            SubjectDomainName = $Properties[2].Value\n                            SubjectLogonId    = $Properties[3].Value\n                            LogonGuid         = $Properties[4].Value.ToString()\n                            TargetUserName    = $Properties[5].Value\n                            TargetDomainName  = $Properties[6].Value\n                            TargetLogonGuid   = $Properties[7].Value\n                            TargetServerName  = $Properties[8].Value\n                            TargetInfo        = $Properties[9].Value\n                            ProcessId         = $Properties[10].Value\n                            ProcessName       = $Properties[11].Value\n                            IpAddress         = $Properties[12].Value\n                            IpPort            = $Properties[13].Value\n                        }\n\n                        if(-not $ReturnHashtables) {\n                            $Output = New-Object PSObject -Property $Output\n                            $Output.PSObject.TypeNames.Insert(0, 'ExplicitCredentialLogonEvent')\n                        }\n\n                        break\n                    }\n                }\n\n                # New local account\n                4720\n                {\n                    $Output = @{\n                        TimeCreated         = $Event.TimeCreated\n                        EventId             = $Event.Id\n                        TargetUserName      = $Properties[0].Value\n                        TargetDomainName    = $Properties[1].Value\n                        TargetSid           = $Properties[2].Value.ToString()\n                        SubjectUserSid      = $Properties[3].Value.ToString()\n                        SubjectUserName     = $Properties[4].Value\n                        SubjectDomainName   = $Properties[5].Value\n                        SubjectLogonId      = $Properties[6].Value\n                        PrivilegeList       = $Properties[7].Value\n                        SamAccountName      = $Properties[8].Value\n                        DisplayName         = $Properties[9].Value\n                        UserPrincipalName   = $Properties[10].Value\n                        HomeDirectory       = $Properties[11].Value\n                        HomePath            = $Properties[12].Value\n                        ScriptPath          = $Properties[13].Value\n                        ProfilePath         = $Properties[14].Value\n                        UserWorkstations    = $Properties[15].Value\n                        PasswordLastSet     = $Properties[16].Value\n                        AccountExpires      = $Properties[17].Value\n                        PrimaryGroupId      = $Properties[18].Value\n                        AllowedToDelegateTo = $Properties[19].Value\n                        OldUacValue         = $Properties[20].Value\n                        NewUacValue         = $Properties[21].Value\n                        UserAccountControl  = $Properties[22].Value\n                        UserParameters      = $Properties[23].Value\n                        SidHistory          = $Properties[24].Value\n                        LogonHours          = $Properties[25].Value\n                    }\n\n                    if(-not $ReturnHashtables) {\n                        $Output = New-Object PSObject -Property $Output\n                        $Output.PSObject.TypeNames.Insert(0, 'LocalAccountCreatedEvent')\n                    }\n\n                    break\n                }\n\n                # Local account deleted\n                4726\n                {\n                    $Output = @{\n                        TimeCreated      = $Event.TimeCreated\n                        EventId          = $Event.Id\n                        TargetUserName    = $Properties[0].Value\n                        TargetDomainName  = $Properties[1].Value\n                        TargetSid         = $Properties[2].Value.ToString()\n                        SubjectUserSid    = $Properties[3].Value.ToString()\n                        SubjectUserName   = $Properties[4].Value\n                        SubjectDomainName = $Properties[5].Value\n                        SubjectLogonId    = $Properties[6].Value\n                        PrivilegeList     = $Properties[7].Value\n                    }\n\n                    if(-not $ReturnHashtables) {\n                        $Output = New-Object PSObject -Property $Output\n                        $Output.PSObject.TypeNames.Insert(0, 'LocalAccountDeletedEvent')\n                    }\n\n                    break\n                }\n\n                # Local admins changed\n                { @(4732,4733) -contains $_ }\n                {\n                    $MemberName = $Properties[0].Value\n                    if($MemberName -eq '-' -and ($Properties[1].Value.ToString()) -match '^S-\\d-(\\d+-){1,14}\\d+$')\n                    {\n                        $MemberName = Convert-SidToName ($Properties[1].Value.ToString())\n                    }\n\n                    if($_ -eq 4732) { $Action = 'AddToGroup' } else {$Action = 'DeleteFromGroup'}\n                    \n                    $Output = @{\n                        TimeCreated       = $Event.TimeCreated\n                        EventId           = $Event.Id\n                        MemberName        = $MemberName\n                        MemberSid         = $Properties[1].Value.ToString()\n                        TargetUserName    = $Properties[2].Value\n                        TargetDomainName  = $Properties[3].Value\n                        TargetSid         = $Properties[4].Value.ToString()\n                        SubjectUserSid    = $Properties[5].Value.ToString()\n                        SubjectUserName   = $Properties[6].Value\n                        SubjectDomainName = $Properties[7].Value\n                        SubjectLogonId    = $Properties[8].Value\n                        PrivilegeList     = $Properties[9].Value\n                        Action            = $Action\n                    }\n\n                    if(-not $ReturnHashtables) {\n                        $Output = New-Object PSObject -Property $Output\n                        $Output.PSObject.TypeNames.Insert(0, 'SecurityGroupChanged')\n                    }\n\n                    break\n                }\n\n                default\n                {\n                    Write-Error \"No handler exists for EID $($Event.Id)\"\n                }\n\n            }\n            $Output\n        }\n    }\n}\n\nStart-AceScript -Uri https://10.182.18.200 -SweepId $args[0] -ScanId ([Guid]::NewGuid()) -RoutingKey siem -Thumbprint 8D1DB3B7B85B6F9E9DE87B291DF66692A10240AE"
  },
  {
    "path": "ACE-Management/PS-ACE/Scripts/ACE_Get-ScheduledJob.ps1",
    "content": "﻿function Start-AceScript\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $SweepId,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $ScanId,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $RoutingKey,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Thumbprint\n    )\n\n    $HostFQDN = Get-WmiObject Win32_ComputerSystem -Property 'Name','Domain' | ForEach-Object {\"$($_.Name).$($_.Domain)\"}\n    $ResultDate = (Get-Date).ToString(\"yyyyMMddThhmmssmsmsZ\")\n\n    $dataList = New-Object -TypeName System.Collections.Generic.List['string']\n\n    foreach($o in (Get-WmiObject -Class Win32_ScheduledJob))\n    {\n        $o.Add('ComputerName', $HostFQDN)\n        $o.Add('ScanType', 'ScheduledJob')\n        $o.Add('SweepId', $SweepId)\n        $o.Add('ScanId', $ScanId)\n        $o.Add('ResultDate', $ResultDate)\n\n        $message = ConvertTo-JsonV2 -InputObject $o\n        $dataList.Add($message)\n    }\n\n    $props = @{\n        ComputerName = $HostFQDN\n        ScanType     = 'ScheduledJob'\n        RoutingKey   = $RoutingKey\n        ResultDate   = $ResultDate\n        ScanId       = $ScanId\n        Data         = $dataList.ToArray()\n    }\n\n    $body = (ConvertTo-JsonV2 -InputObject $props)\n    \n    Write-Host $body\n    \n    Invoke-AceWebRequest -Thumbprint $Thumbprint -Uri \"$($Uri)/ace/result/$($SweepId)\" -Body $body\n}\n\nfunction ConvertTo-JsonV2 \n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        $InputObject\n    )\n\n    Begin \n    {\n        $null = [System.Reflection.Assembly]::LoadWithPartialName(\"System.Web.Extensions\")\n        $Serializer = New-Object System.Web.Script.Serialization.JavaScriptSerializer\n    }\n\n    Process \n    {\n        try \n        {\n            $Serializer.Serialize($InputObject)\n        } \n        catch \n        {\n            Write-Error $_\n        }    \n    }\n}\n\nfunction Invoke-AceWebRequest\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Thumbprint,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Body\n    )\n\n    [Net.ServicePointManager]::ServerCertificateValidationCallback = {\n        $Thumbprint = $Thumbprint\n        $certificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]$args[1]\n    \n        if ($certificate -eq $null)\n        {\n            $Host.UI.WriteErrorLine(\"Null certificate.\")\n            return $true\n        }\n    \n        if ($certificate.Thumbprint -eq $Thumbprint)\n        {\n            return $true\n        }\n        else\n        {\n            $Host.UI.WriteErrorLine(\"Thumbprint mismatch. Certificate thumbprint $($certificate.Thumbprint)\")\n        }\n    \n        return $false\n    }\n\n    try\n    {\n        Write-Host \"URI: $($Uri)\"\n\n        # Create web request\n        $WebRequest = [Net.WebRequest]::Create($uri)\n        $WebRequest.Method = 'Post'\n        $WebRequest.ContentType = 'application/json'\n        $WebRequest.Headers.Add('X-API-Version:1.0')\n\n        $byteArray = [System.Text.Encoding]::UTF8.GetBytes($Body)\n        $Webrequest.ContentLength = $byteArray.Length\n        \n        $dataStream = $Webrequest.GetRequestStream()            \n        $dataStream.Write($byteArray, 0, $byteArray.Length)\n        $dataStream.Close()\n\n        # Get response stream\n        $ResponseStream = $Webrequest.GetResponse().GetResponseStream()\n    \n        # Create a stream reader and read the stream returning the string value.\n        $StreamReader = New-Object System.IO.StreamReader -ArgumentList $ResponseStream\n        $StreamReader.ReadToEnd()\n    }\n    catch\n    {\n        Write-Error \"Failed: $($_.exception.innerexception.message)\"\n    }\n}\n\nStart-AceScript -Uri https://10.182.18.200 -SweepId $args[0] -ScanId ([Guid]::NewGuid()) -RoutingKey siem -Thumbprint 8D1DB3B7B85B6F9E9DE87B291DF66692A10240AE"
  },
  {
    "path": "ACE-Management/PS-ACE/Scripts/ACE_Get-SecurityPackage.ps1",
    "content": "﻿function Start-AceScript\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $SweepId,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $ScanId,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $RoutingKey,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Thumbprint\n    )\n\n    $HostFQDN = Get-WmiObject Win32_ComputerSystem -Property 'Name','Domain' | ForEach-Object {\"$($_.Name).$($_.Domain)\"}\n    $ResultDate = (Get-Date).ToString(\"yyyyMMddThhmmssmsmsZ\")\n\n    $dataList = New-Object -TypeName System.Collections.Generic.List['string']\n\n    foreach($o in (Get-SecurityPackage -ReturnHashtables))\n    {\n        $o.Add('ComputerName', $HostFQDN)\n        $o.Add('ScanType', 'SecruityPackage')\n        $o.Add('SweepId', $SweepId)\n        $o.Add('ScanId', $ScanId)\n        $o.Add('ResultDate', $ResultDate)\n        \n        $message = ConvertTo-JsonV2 -InputObject $o\n        $dataList.Add($message)\n    }\n    \n    $props = @{\n        ComputerName = $HostFQDN\n        ScanType     = 'SecurityPackage'\n        RoutingKey   = $RoutingKey\n        ResultDate   = $ResultDate\n        ScanId       = $ScanId\n        Data         = $dataList.ToArray()\n    }\n\n    $body = (ConvertTo-JsonV2 -InputObject $props)\n\n    Write-Host $body\n\n    Invoke-AceWebRequest -Thumbprint $Thumbprint -Uri \"$($Uri)/ace/result/$($SweepId)\" -Body $body\n}\n\nfunction ConvertTo-JsonV2 \n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        $InputObject\n    )\n\n    Begin \n    {\n        $null = [System.Reflection.Assembly]::LoadWithPartialName(\"System.Web.Extensions\")\n        $Serializer = New-Object System.Web.Script.Serialization.JavaScriptSerializer\n    }\n\n    Process \n    {\n        try \n        {\n            $Serializer.Serialize($InputObject)\n        } \n        catch \n        {\n            Write-Error $_\n        }    \n    }\n}\n\nfunction Invoke-AceWebRequest\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Thumbprint,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Body\n    )\n\n    [Net.ServicePointManager]::ServerCertificateValidationCallback = {\n        $Thumbprint = $Thumbprint\n        $certificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]$args[1]\n    \n        if ($certificate -eq $null)\n        {\n            $Host.UI.WriteErrorLine(\"Null certificate.\")\n            return $true\n        }\n    \n        if ($certificate.Thumbprint -eq $Thumbprint)\n        {\n            return $true\n        }\n        else\n        {\n            $Host.UI.WriteErrorLine(\"Thumbprint mismatch. Certificate thumbprint $($certificate.Thumbprint)\")\n        }\n    \n        return $false\n    }\n\n    try\n    {\n        Write-Host \"URI: $($Uri)\"\n\n        # Create web request\n        $WebRequest = [Net.WebRequest]::Create($uri)\n        $WebRequest.Method = 'Post'\n        $WebRequest.ContentType = 'application/json'\n        $WebRequest.Headers.Add('X-API-Version:1.0')\n\n        $byteArray = [System.Text.Encoding]::UTF8.GetBytes($Body)\n        $Webrequest.ContentLength = $byteArray.Length\n        \n        $dataStream = $Webrequest.GetRequestStream()            \n        $dataStream.Write($byteArray, 0, $byteArray.Length)\n        $dataStream.Close()\n\n        # Get response stream\n        $ResponseStream = $Webrequest.GetResponse().GetResponseStream()\n    \n        # Create a stream reader and read the stream returning the string value.\n        $StreamReader = New-Object System.IO.StreamReader -ArgumentList $ResponseStream\n        $StreamReader.ReadToEnd()\n    }\n    catch\n    {\n        Write-Error \"Failed: $($_.exception.innerexception.message)\"\n    }\n}\n\nfunction Get-SecurityPackage\n{\n    param\n    (\n        [Parameter()]\n        [switch]\n        $ReturnHashtables\n    )\n    <#\n    .SYNOPSIS\n\n    Enumerates Security Service Providers (SSP) t\n\n    .DESCRIPTION   \n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: None\n    Optional Dependencies: None\n\n    .EXAMPLE\n\n    PS > Get-SecurityPackage\n\n    Name         : Negotiate\n    Comment      : Microsoft Package Negotiator\n    Capabilities : INTEGRITY, PRIVACY, CONNECTION, MULTI_REQUIRED, EXTENDED_ERROR, \n                   IMPERSONATION, ACCEPT_WIN32_NAME, NEGOTIABLE, GSS_COMPATIBLE, LOGON, \n                   RESTRICTED_TOKENS, APPCONTAINER_CHECKS\n    Version      : 1\n    RpcId        : 9\n    MaxToken     : 65791\n\n    Name         : NegoExtender\n    Comment      : NegoExtender Security Package\n    Capabilities : INTEGRITY, PRIVACY, CONNECTION, IMPERSONATION, NEGOTIABLE, GSS_COMPATIBLE, \n                   LOGON, MUTUAL_AUTH, NEGO_EXTENDER, APPCONTAINER_CHECKS\n    Version      : 1\n    RpcId        : 30\n    MaxToken     : 12000\n\n    Name         : Kerberos\n    Comment      : Microsoft Kerberos V1.0\n    Capabilities : INTEGRITY, PRIVACY, TOKEN_ONLY, DATAGRAM, CONNECTION, MULTI_REQUIRED, \n                   EXTENDED_ERROR, IMPERSONATION, ACCEPT_WIN32_NAME, NEGOTIABLE, \n                   GSS_COMPATIBLE, LOGON, MUTUAL_AUTH, DELEGATION, READONLY_WITH_CHECKSUM, \n                   RESTRICTED_TOKENS, APPCONTAINER_CHECKS\n    Version      : 1\n    RpcId        : 16\n    MaxToken     : 65535\n\n    Name         : NTLM\n    Comment      : NTLM Security Package\n    Capabilities : INTEGRITY, PRIVACY, TOKEN_ONLY, CONNECTION, MULTI_REQUIRED, IMPERSONATION, \n                   ACCEPT_WIN32_NAME, NEGOTIABLE, LOGON, RESTRICTED_TOKENS, APPCONTAINER_CHECKS\n    Version      : 1\n    RpcId        : 10\n    MaxToken     : 2888\n\n    Name         : TSSSP\n    Comment      : TS Service Security Package\n    Capabilities : CONNECTION, MULTI_REQUIRED, ACCEPT_WIN32_NAME, MUTUAL_AUTH, \n                   APPCONTAINER_CHECKS\n    Version      : 1\n    RpcId        : 22\n    MaxToken     : 13000\n\n    Name         : pku2u\n    Comment      : PKU2U Security Package\n    Capabilities : INTEGRITY, PRIVACY, CONNECTION, IMPERSONATION, GSS_COMPATIBLE, MUTUAL_AUTH, \n                   NEGOTIABLE2, APPCONTAINER_CHECKS\n    Version      : 1\n    RpcId        : 31\n    MaxToken     : 12000\n\n    Name         : CloudAP\n    Comment      : Cloud AP Security Package\n    Capabilities : LOGON, NEGOTIABLE2\n    Version      : 1\n    RpcId        : 36\n    MaxToken     : 0\n\n    Name         : WDigest\n    Comment      : Digest Authentication for Windows\n    Capabilities : TOKEN_ONLY, IMPERSONATION, ACCEPT_WIN32_NAME, APPCONTAINER_CHECKS\n    Version      : 1\n    RpcId        : 21\n    MaxToken     : 4096\n\n    Name         : Schannel\n    Comment      : Schannel Security Package\n    Capabilities : INTEGRITY, PRIVACY, CONNECTION, MULTI_REQUIRED, EXTENDED_ERROR, \n                   IMPERSONATION, ACCEPT_WIN32_NAME, STREAM, MUTUAL_AUTH, \n                   APPCONTAINER_PASSTHROUGH\n    Version      : 1\n    RpcId        : 14\n    MaxToken     : 24576\n\n    Name         : Microsoft Unified Security Protocol Provider\n    Comment      : Schannel Security Package\n    Capabilities : INTEGRITY, PRIVACY, CONNECTION, MULTI_REQUIRED, EXTENDED_ERROR, \n                   IMPERSONATION, ACCEPT_WIN32_NAME, STREAM, MUTUAL_AUTH, \n                   APPCONTAINER_PASSTHROUGH\n    Version      : 1\n    RpcId        : 14\n    MaxToken     : 24576\n\n    Name         : CREDSSP\n    Comment      : Microsoft CredSSP Security Provider\n    Capabilities : INTEGRITY, PRIVACY, CONNECTION, MULTI_REQUIRED, IMPERSONATION, \n                   ACCEPT_WIN32_NAME, STREAM, MUTUAL_AUTH, APPCONTAINER_CHECKS\n    Version      : 1\n    RpcId        : 65535\n    MaxToken     : 90567\n    #>\n\n    $obj = EnumerateSecurityPackages\n\n    if($ReturnHashtables)\n    {\n        foreach($o in $obj)\n        {\n            $props = @{\n                Name = $o.Name\n                Comment = $o.Comment\n                Capabilities = $o.Capabilities\n                Version = $o.Version\n                RpcId = $o.RpcId\n                MaxToken = $o.MaxToken\n            }\n\n            Write-Output $props\n        }\n    }\n    else\n    {\n        Write-Output $obj\n    }\n}\n\n#region PSReflect\n\nfunction New-InMemoryModule\n{\n<#\n.SYNOPSIS\n\nCreates an in-memory assembly and module\n\nAuthor: Matthew Graeber (@mattifestation)\nLicense: BSD 3-Clause\nRequired Dependencies: None\nOptional Dependencies: None\n \n.DESCRIPTION\n\nWhen defining custom enums, structs, and unmanaged functions, it is\nnecessary to associate to an assembly module. This helper function\ncreates an in-memory module that can be passed to the 'enum',\n'struct', and Add-Win32Type functions.\n\n.PARAMETER ModuleName\n\nSpecifies the desired name for the in-memory assembly and module. If\nModuleName is not provided, it will default to a GUID.\n\n.EXAMPLE\n\n$Module = New-InMemoryModule -ModuleName Win32\n#>\n\n    Param\n    (\n        [Parameter(Position = 0)]\n        [ValidateNotNullOrEmpty()]\n        [String]\n        $ModuleName = [Guid]::NewGuid().ToString()\n    )\n\n    $AppDomain = [Reflection.Assembly].Assembly.GetType('System.AppDomain').GetProperty('CurrentDomain').GetValue($null, @())\n    $LoadedAssemblies = $AppDomain.GetAssemblies()\n\n    foreach ($Assembly in $LoadedAssemblies) {\n        if ($Assembly.FullName -and ($Assembly.FullName.Split(',')[0] -eq $ModuleName)) {\n            return $Assembly\n        }\n    }\n\n    $DynAssembly = New-Object Reflection.AssemblyName($ModuleName)\n    $Domain = $AppDomain\n    $AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, 'Run')\n    $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule($ModuleName, $False)\n\n    return $ModuleBuilder\n}\n\n# A helper function used to reduce typing while defining function\n# prototypes for Add-Win32Type.\nfunction func\n{\n    Param\n    (\n        [Parameter(Position = 0, Mandatory = $True)]\n        [String]\n        $DllName,\n\n        [Parameter(Position = 1, Mandatory = $True)]\n        [string]\n        $FunctionName,\n\n        [Parameter(Position = 2, Mandatory = $True)]\n        [Type]\n        $ReturnType,\n\n        [Parameter(Position = 3)]\n        [Type[]]\n        $ParameterTypes,\n\n        [Parameter(Position = 4)]\n        [Runtime.InteropServices.CallingConvention]\n        $NativeCallingConvention,\n\n        [Parameter(Position = 5)]\n        [Runtime.InteropServices.CharSet]\n        $Charset,\n\n        [String]\n        $EntryPoint,\n\n        [Switch]\n        $SetLastError\n    )\n\n    $Properties = @{\n        DllName = $DllName\n        FunctionName = $FunctionName\n        ReturnType = $ReturnType\n    }\n\n    if ($ParameterTypes) { $Properties['ParameterTypes'] = $ParameterTypes }\n    if ($NativeCallingConvention) { $Properties['NativeCallingConvention'] = $NativeCallingConvention }\n    if ($Charset) { $Properties['Charset'] = $Charset }\n    if ($SetLastError) { $Properties['SetLastError'] = $SetLastError }\n    if ($EntryPoint) { $Properties['EntryPoint'] = $EntryPoint }\n\n    New-Object PSObject -Property $Properties\n}\n\nfunction Add-Win32Type\n{\n<#\n.SYNOPSIS\n\nCreates a .NET type for an unmanaged Win32 function.\n\nAuthor: Matthew Graeber (@mattifestation)\nLicense: BSD 3-Clause\nRequired Dependencies: None\nOptional Dependencies: func\n \n.DESCRIPTION\n\nAdd-Win32Type enables you to easily interact with unmanaged (i.e.\nWin32 unmanaged) functions in PowerShell. After providing\nAdd-Win32Type with a function signature, a .NET type is created\nusing reflection (i.e. csc.exe is never called like with Add-Type).\n\nThe 'func' helper function can be used to reduce typing when defining\nmultiple function definitions.\n\n.PARAMETER DllName\n\nThe name of the DLL.\n\n.PARAMETER FunctionName\n\nThe name of the target function.\n\n.PARAMETER EntryPoint\n\nThe DLL export function name. This argument should be specified if the\nspecified function name is different than the name of the exported\nfunction.\n\n.PARAMETER ReturnType\n\nThe return type of the function.\n\n.PARAMETER ParameterTypes\n\nThe function parameters.\n\n.PARAMETER NativeCallingConvention\n\nSpecifies the native calling convention of the function. Defaults to\nstdcall.\n\n.PARAMETER Charset\n\nIf you need to explicitly call an 'A' or 'W' Win32 function, you can\nspecify the character set.\n\n.PARAMETER SetLastError\n\nIndicates whether the callee calls the SetLastError Win32 API\nfunction before returning from the attributed method.\n\n.PARAMETER Module\n\nThe in-memory module that will host the functions. Use\nNew-InMemoryModule to define an in-memory module.\n\n.PARAMETER Namespace\n\nAn optional namespace to prepend to the type. Add-Win32Type defaults\nto a namespace consisting only of the name of the DLL.\n\n.EXAMPLE\n\n$Mod = New-InMemoryModule -ModuleName Win32\n\n$FunctionDefinitions = @(\n  (func kernel32 GetProcAddress ([IntPtr]) @([IntPtr], [String]) -Charset Ansi -SetLastError),\n  (func kernel32 GetModuleHandle ([Intptr]) @([String]) -SetLastError),\n  (func ntdll RtlGetCurrentPeb ([IntPtr]) @())\n)\n\n$Types = $FunctionDefinitions | Add-Win32Type -Module $Mod -Namespace 'Win32'\n$Kernel32 = $Types['kernel32']\n$Ntdll = $Types['ntdll']\n$Ntdll::RtlGetCurrentPeb()\n$ntdllbase = $Kernel32::GetModuleHandle('ntdll')\n$Kernel32::GetProcAddress($ntdllbase, 'RtlGetCurrentPeb')\n\n.NOTES\n\nInspired by Lee Holmes' Invoke-WindowsApi http://poshcode.org/2189\n\nWhen defining multiple function prototypes, it is ideal to provide\nAdd-Win32Type with an array of function signatures. That way, they\nare all incorporated into the same in-memory module.\n#>\n\n    [OutputType([Hashtable])]\n    Param(\n        [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)]\n        [String]\n        $DllName,\n\n        [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)]\n        [String]\n        $FunctionName,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [String]\n        $EntryPoint,\n\n        [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)]\n        [Type]\n        $ReturnType,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [Type[]]\n        $ParameterTypes,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [Runtime.InteropServices.CallingConvention]\n        $NativeCallingConvention = [Runtime.InteropServices.CallingConvention]::StdCall,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [Runtime.InteropServices.CharSet]\n        $Charset = [Runtime.InteropServices.CharSet]::Auto,\n\n        [Parameter(ValueFromPipelineByPropertyName = $True)]\n        [Switch]\n        $SetLastError,\n\n        [Parameter(Mandatory = $True)]\n        [ValidateScript({($_ -is [Reflection.Emit.ModuleBuilder]) -or ($_ -is [Reflection.Assembly])})]\n        $Module,\n\n        [ValidateNotNull()]\n        [String]\n        $Namespace = ''\n    )\n\n    BEGIN\n    {\n        $TypeHash = @{}\n    }\n\n    PROCESS\n    {\n        if ($Module -is [Reflection.Assembly])\n        {\n            if ($Namespace)\n            {\n                $TypeHash[$DllName] = $Module.GetType(\"$Namespace.$DllName\")\n            }\n            else\n            {\n                $TypeHash[$DllName] = $Module.GetType($DllName)\n            }\n        }\n        else\n        {\n            # Define one type for each DLL\n            if (!$TypeHash.ContainsKey($DllName))\n            {\n                if ($Namespace)\n                {\n                    $TypeHash[$DllName] = $Module.DefineType(\"$Namespace.$DllName\", 'Public,BeforeFieldInit')\n                }\n                else\n                {\n                    $TypeHash[$DllName] = $Module.DefineType($DllName, 'Public,BeforeFieldInit')\n                }\n            }\n\n            $Method = $TypeHash[$DllName].DefineMethod(\n                $FunctionName,\n                'Public,Static,PinvokeImpl',\n                $ReturnType,\n                $ParameterTypes)\n\n            # Make each ByRef parameter an Out parameter\n            $i = 1\n            foreach($Parameter in $ParameterTypes)\n            {\n                if ($Parameter.IsByRef)\n                {\n                    [void] $Method.DefineParameter($i, 'Out', $null)\n                }\n\n                $i++\n            }\n\n            $DllImport = [Runtime.InteropServices.DllImportAttribute]\n            $SetLastErrorField = $DllImport.GetField('SetLastError')\n            $CallingConventionField = $DllImport.GetField('CallingConvention')\n            $CharsetField = $DllImport.GetField('CharSet')\n            $EntryPointField = $DllImport.GetField('EntryPoint')\n            if ($SetLastError) { $SLEValue = $True } else { $SLEValue = $False }\n\n            if ($PSBoundParameters['EntryPoint']) { $ExportedFuncName = $EntryPoint } else { $ExportedFuncName = $FunctionName }\n\n            # Equivalent to C# version of [DllImport(DllName)]\n            $Constructor = [Runtime.InteropServices.DllImportAttribute].GetConstructor([String])\n            $DllImportAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($Constructor,\n                $DllName, [Reflection.PropertyInfo[]] @(), [Object[]] @(),\n                [Reflection.FieldInfo[]] @($SetLastErrorField,\n                                           $CallingConventionField,\n                                           $CharsetField,\n                                           $EntryPointField),\n                [Object[]] @($SLEValue,\n                             ([Runtime.InteropServices.CallingConvention] $NativeCallingConvention),\n                             ([Runtime.InteropServices.CharSet] $Charset),\n                             $ExportedFuncName))\n\n            $Method.SetCustomAttribute($DllImportAttribute)\n        }\n    }\n\n    END\n    {\n        if ($Module -is [Reflection.Assembly])\n        {\n            return $TypeHash\n        }\n\n        $ReturnTypes = @{}\n\n        foreach ($Key in $TypeHash.Keys)\n        {\n            $Type = $TypeHash[$Key].CreateType()\n            \n            $ReturnTypes[$Key] = $Type\n        }\n\n        return $ReturnTypes\n    }\n}\n\nfunction psenum\n{\n<#\n.SYNOPSIS\n\nCreates an in-memory enumeration for use in your PowerShell session.\n\nAuthor: Matthew Graeber (@mattifestation)\nLicense: BSD 3-Clause\nRequired Dependencies: None\nOptional Dependencies: None\n \n.DESCRIPTION\n\nThe 'psenum' function facilitates the creation of enums entirely in\nmemory using as close to a \"C style\" as PowerShell will allow.\n\n.PARAMETER Module\n\nThe in-memory module that will host the enum. Use\nNew-InMemoryModule to define an in-memory module.\n\n.PARAMETER FullName\n\nThe fully-qualified name of the enum.\n\n.PARAMETER Type\n\nThe type of each enum element.\n\n.PARAMETER EnumElements\n\nA hashtable of enum elements.\n\n.PARAMETER Bitfield\n\nSpecifies that the enum should be treated as a bitfield.\n\n.EXAMPLE\n\n$Mod = New-InMemoryModule -ModuleName Win32\n\n$ImageSubsystem = psenum $Mod PE.IMAGE_SUBSYSTEM UInt16 @{\n    UNKNOWN =                  0\n    NATIVE =                   1 # Image doesn't require a subsystem.\n    WINDOWS_GUI =              2 # Image runs in the Windows GUI subsystem.\n    WINDOWS_CUI =              3 # Image runs in the Windows character subsystem.\n    OS2_CUI =                  5 # Image runs in the OS/2 character subsystem.\n    POSIX_CUI =                7 # Image runs in the Posix character subsystem.\n    NATIVE_WINDOWS =           8 # Image is a native Win9x driver.\n    WINDOWS_CE_GUI =           9 # Image runs in the Windows CE subsystem.\n    EFI_APPLICATION =          10\n    EFI_BOOT_SERVICE_DRIVER =  11\n    EFI_RUNTIME_DRIVER =       12\n    EFI_ROM =                  13\n    XBOX =                     14\n    WINDOWS_BOOT_APPLICATION = 16\n}\n\n.NOTES\n\nPowerShell purists may disagree with the naming of this function but\nagain, this was developed in such a way so as to emulate a \"C style\"\ndefinition as closely as possible. Sorry, I'm not going to name it\nNew-Enum. :P\n#>\n\n    [OutputType([Type])]\n    Param\n    (\n        [Parameter(Position = 0, Mandatory = $True)]\n        [ValidateScript({($_ -is [Reflection.Emit.ModuleBuilder]) -or ($_ -is [Reflection.Assembly])})]\n        $Module,\n\n        [Parameter(Position = 1, Mandatory = $True)]\n        [ValidateNotNullOrEmpty()]\n        [String]\n        $FullName,\n\n        [Parameter(Position = 2, Mandatory = $True)]\n        [Type]\n        $Type,\n\n        [Parameter(Position = 3, Mandatory = $True)]\n        [ValidateNotNullOrEmpty()]\n        [Hashtable]\n        $EnumElements,\n\n        [Switch]\n        $Bitfield\n    )\n\n    if ($Module -is [Reflection.Assembly])\n    {\n        return ($Module.GetType($FullName))\n    }\n\n    $EnumType = $Type -as [Type]\n\n    $EnumBuilder = $Module.DefineEnum($FullName, 'Public', $EnumType)\n\n    if ($Bitfield)\n    {\n        $FlagsConstructor = [FlagsAttribute].GetConstructor(@())\n        $FlagsCustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($FlagsConstructor, @())\n        $EnumBuilder.SetCustomAttribute($FlagsCustomAttribute)\n    }\n\n    foreach ($Key in $EnumElements.Keys)\n    {\n        # Apply the specified enum type to each element\n        $null = $EnumBuilder.DefineLiteral($Key, $EnumElements[$Key] -as $EnumType)\n    }\n\n    $EnumBuilder.CreateType()\n}\n\n# A helper function used to reduce typing while defining struct\n# fields.\nfunction field\n{\n    Param\n    (\n        [Parameter(Position = 0, Mandatory = $True)]\n        [UInt16]\n        $Position,\n        \n        [Parameter(Position = 1, Mandatory = $True)]\n        [Type]\n        $Type,\n        \n        [Parameter(Position = 2)]\n        [UInt16]\n        $Offset,\n        \n        [Object[]]\n        $MarshalAs\n    )\n\n    @{\n        Position = $Position\n        Type = $Type -as [Type]\n        Offset = $Offset\n        MarshalAs = $MarshalAs\n    }\n}\n\nfunction struct\n{\n<#\n.SYNOPSIS\n\nCreates an in-memory struct for use in your PowerShell session.\n\nAuthor: Matthew Graeber (@mattifestation)\nLicense: BSD 3-Clause\nRequired Dependencies: None\nOptional Dependencies: field\n \n.DESCRIPTION\n\nThe 'struct' function facilitates the creation of structs entirely in\nmemory using as close to a \"C style\" as PowerShell will allow. Struct\nfields are specified using a hashtable where each field of the struct\nis comprosed of the order in which it should be defined, its .NET\ntype, and optionally, its offset and special marshaling attributes.\n\nOne of the features of 'struct' is that after your struct is defined,\nit will come with a built-in GetSize method as well as an explicit\nconverter so that you can easily cast an IntPtr to the struct without\nrelying upon calling SizeOf and/or PtrToStructure in the Marshal\nclass.\n\n.PARAMETER Module\n\nThe in-memory module that will host the struct. Use\nNew-InMemoryModule to define an in-memory module.\n\n.PARAMETER FullName\n\nThe fully-qualified name of the struct.\n\n.PARAMETER StructFields\n\nA hashtable of fields. Use the 'field' helper function to ease\ndefining each field.\n\n.PARAMETER PackingSize\n\nSpecifies the memory alignment of fields.\n\n.PARAMETER ExplicitLayout\n\nIndicates that an explicit offset for each field will be specified.\n\n.EXAMPLE\n\n$Mod = New-InMemoryModule -ModuleName Win32\n\n$ImageDosSignature = psenum $Mod PE.IMAGE_DOS_SIGNATURE UInt16 @{\n    DOS_SIGNATURE =    0x5A4D\n    OS2_SIGNATURE =    0x454E\n    OS2_SIGNATURE_LE = 0x454C\n    VXD_SIGNATURE =    0x454C\n}\n\n$ImageDosHeader = struct $Mod PE.IMAGE_DOS_HEADER @{\n    e_magic =    field 0 $ImageDosSignature\n    e_cblp =     field 1 UInt16\n    e_cp =       field 2 UInt16\n    e_crlc =     field 3 UInt16\n    e_cparhdr =  field 4 UInt16\n    e_minalloc = field 5 UInt16\n    e_maxalloc = field 6 UInt16\n    e_ss =       field 7 UInt16\n    e_sp =       field 8 UInt16\n    e_csum =     field 9 UInt16\n    e_ip =       field 10 UInt16\n    e_cs =       field 11 UInt16\n    e_lfarlc =   field 12 UInt16\n    e_ovno =     field 13 UInt16\n    e_res =      field 14 UInt16[] -MarshalAs @('ByValArray', 4)\n    e_oemid =    field 15 UInt16\n    e_oeminfo =  field 16 UInt16\n    e_res2 =     field 17 UInt16[] -MarshalAs @('ByValArray', 10)\n    e_lfanew =   field 18 Int32\n}\n\n# Example of using an explicit layout in order to create a union.\n$TestUnion = struct $Mod TestUnion @{\n    field1 = field 0 UInt32 0\n    field2 = field 1 IntPtr 0\n} -ExplicitLayout\n\n.NOTES\n\nPowerShell purists may disagree with the naming of this function but\nagain, this was developed in such a way so as to emulate a \"C style\"\ndefinition as closely as possible. Sorry, I'm not going to name it\nNew-Struct. :P\n#>\n\n    [OutputType([Type])]\n    Param\n    (\n        [Parameter(Position = 1, Mandatory = $True)]\n        [ValidateScript({($_ -is [Reflection.Emit.ModuleBuilder]) -or ($_ -is [Reflection.Assembly])})]\n        $Module,\n\n        [Parameter(Position = 2, Mandatory = $True)]\n        [ValidateNotNullOrEmpty()]\n        [String]\n        $FullName,\n\n        [Parameter(Position = 3, Mandatory = $True)]\n        [ValidateNotNullOrEmpty()]\n        [Hashtable]\n        $StructFields,\n\n        [Reflection.Emit.PackingSize]\n        $PackingSize = [Reflection.Emit.PackingSize]::Unspecified,\n\n        [Switch]\n        $ExplicitLayout\n    )\n\n    if ($Module -is [Reflection.Assembly])\n    {\n        return ($Module.GetType($FullName))\n    }\n\n    [Reflection.TypeAttributes] $StructAttributes = 'AnsiClass,\n        Class,\n        Public,\n        Sealed,\n        BeforeFieldInit'\n\n    if ($ExplicitLayout)\n    {\n        $StructAttributes = $StructAttributes -bor [Reflection.TypeAttributes]::ExplicitLayout\n    }\n    else\n    {\n        $StructAttributes = $StructAttributes -bor [Reflection.TypeAttributes]::SequentialLayout\n    }\n\n    $StructBuilder = $Module.DefineType($FullName, $StructAttributes, [ValueType], $PackingSize)\n    $ConstructorInfo = [Runtime.InteropServices.MarshalAsAttribute].GetConstructors()[0]\n    $SizeConst = @([Runtime.InteropServices.MarshalAsAttribute].GetField('SizeConst'))\n\n    $Fields = New-Object Hashtable[]($StructFields.Count)\n\n    # Sort each field according to the orders specified\n    # Unfortunately, PSv2 doesn't have the luxury of the\n    # hashtable [Ordered] accelerator.\n    foreach ($Field in $StructFields.Keys)\n    {\n        $Index = $StructFields[$Field]['Position']\n        $Fields[$Index] = @{FieldName = $Field; Properties = $StructFields[$Field]}\n    }\n\n    foreach ($Field in $Fields)\n    {\n        $FieldName = $Field['FieldName']\n        $FieldProp = $Field['Properties']\n\n        $Offset = $FieldProp['Offset']\n        $Type = $FieldProp['Type']\n        $MarshalAs = $FieldProp['MarshalAs']\n\n        $NewField = $StructBuilder.DefineField($FieldName, $Type, 'Public')\n\n        if ($MarshalAs)\n        {\n            $UnmanagedType = $MarshalAs[0] -as ([Runtime.InteropServices.UnmanagedType])\n            if ($MarshalAs[1])\n            {\n                $Size = $MarshalAs[1]\n                $AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($ConstructorInfo,\n                    $UnmanagedType, $SizeConst, @($Size))\n            }\n            else\n            {\n                $AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($ConstructorInfo, [Object[]] @($UnmanagedType))\n            }\n            \n            $NewField.SetCustomAttribute($AttribBuilder)\n        }\n\n        if ($ExplicitLayout) { $NewField.SetOffset($Offset) }\n    }\n\n    # Make the struct aware of its own size.\n    # No more having to call [Runtime.InteropServices.Marshal]::SizeOf!\n    $SizeMethod = $StructBuilder.DefineMethod('GetSize',\n        'Public, Static',\n        [Int],\n        [Type[]] @())\n    $ILGenerator = $SizeMethod.GetILGenerator()\n    # Thanks for the help, Jason Shirk!\n    $ILGenerator.Emit([Reflection.Emit.OpCodes]::Ldtoken, $StructBuilder)\n    $ILGenerator.Emit([Reflection.Emit.OpCodes]::Call,\n        [Type].GetMethod('GetTypeFromHandle'))\n    $ILGenerator.Emit([Reflection.Emit.OpCodes]::Call,\n        [Runtime.InteropServices.Marshal].GetMethod('SizeOf', [Type[]] @([Type])))\n    $ILGenerator.Emit([Reflection.Emit.OpCodes]::Ret)\n\n    # Allow for explicit casting from an IntPtr\n    # No more having to call [Runtime.InteropServices.Marshal]::PtrToStructure!\n    $ImplicitConverter = $StructBuilder.DefineMethod('op_Implicit',\n        'PrivateScope, Public, Static, HideBySig, SpecialName',\n        $StructBuilder,\n        [Type[]] @([IntPtr]))\n    $ILGenerator2 = $ImplicitConverter.GetILGenerator()\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Nop)\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ldarg_0)\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ldtoken, $StructBuilder)\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Call,\n        [Type].GetMethod('GetTypeFromHandle'))\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Call,\n        [Runtime.InteropServices.Marshal].GetMethod('PtrToStructure', [Type[]] @([IntPtr], [Type])))\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Unbox_Any, $StructBuilder)\n    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ret)\n\n    $StructBuilder.CreateType()\n}\n\n#endregion PSReflect\n\n$Module = New-InMemoryModule -ModuleName GetSecurityPackage\n\n#region Enums\n$SECPKG_FLAG = psenum $Module SECPKG_FLAG UInt32 @{\n    INTEGRITY                = 0x1\n    PRIVACY                  = 0x2\n    TOKEN_ONLY               = 0x4\n    DATAGRAM                 = 0x8\n    CONNECTION               = 0x10\n    MULTI_REQUIRED           = 0x20\n    CLIENT_ONLY              = 0x40\n    EXTENDED_ERROR           = 0x80\n    IMPERSONATION            = 0x100\n    ACCEPT_WIN32_NAME        = 0x200\n    STREAM                   = 0x400\n    NEGOTIABLE               = 0X800\n    GSS_COMPATIBLE           = 0x1000\n    LOGON                    = 0x2000\n    ASCII_BUFFERS            = 0x4000\n    FRAGMENT                 = 0x8000\n    MUTUAL_AUTH              = 0x10000\n    DELEGATION               = 0x20000\n    READONLY_WITH_CHECKSUM   = 0x40000\n    RESTRICTED_TOKENS        = 0x80000\n    NEGO_EXTENDER            = 0x00100000\n    NEGOTIABLE2              = 0x00200000\n    APPCONTAINER_PASSTHROUGH = 0x00400000\n    APPCONTAINER_CHECKS      = 0x00800000\n\n    #SECPKG_CALLFLAGS_APPCONTAINER = 0x00000001\n    #SECPKG_CALLFLAGS_AUTHCAPABLE = 0x00000002\n    #SECPKG_CALLFLAGS_FORCE_SUPPLIED = 0x00000004\n} -Bitfield\n#endregion Enums\n\n#region Structs\n$SecPkgInfo = struct $Module SecPkgInfo @{\n    Capabilities = field 0 $SECPKG_FLAG\n    Version = field 1 UInt16\n    RPCID = field 2 UInt16\n    MaxToken = field 3 UInt32\n    Name = field 4 IntPtr\n    Comment = field 5 IntPtr\n}\n#endregion Structs\n\n#region Function Definitions\n$FunctionDefinitions = @(\n    (func secur32 DeleteSecurityPackage ([UInt32]) @(\n        [string] #_In_ LPTSTR pszPackageName\n    ) -EntryPoint DeleteSecurityPackage),\n\n    (func secur32 EnumerateSecurityPackages ([UInt32]) @(\n        [UInt32].MakeByRefType(), #_In_ PULONG      pcPackages\n        [IntPtr].MakeByRefType()  #_In_ PSecPkgInfo *ppPackageInfo\n    ) -EntryPoint EnumerateSecurityPackages),\n\n    (func secur32 FreeContextBuffer ([UInt32]) @(\n          [IntPtr] #_In_ PVOID pvContextBuffer\n    ) -EntryPoint FreeContextBuffer)\n)\n\n$Types = $FunctionDefinitions | Add-Win32Type -Module $Module -Namespace GetSecurityPackage\n$Secur32 = $Types['secur32']\n#endregion Function Definitions\n\nfunction DeleteSecurityPackage\n{\n    <#\n    .SYNOPSIS\n\n    Deletes a security support provider from the list of providers supported by Microsoft Negotiate.\n\n    .PARAMETER PackageName\n\n    The name of the security provider to delete.\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: None\n    Optional Dependencies: None\n\n    (func secur32 DeleteSecurityPackage ([UInt32]) @(\n        [string] #_In_ LPTSTR pszPackageName\n    ) -EntryPoint DeleteSecurityPackage)\n\n    .LINK\n    \n    https://msdn.microsoft.com/en-us/library/windows/desktop/dd401610(v=vs.85).aspx\n    \n    .EXAMPLE\n\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $PackageName\n    )\n\n    $SUCCESS = $Secur32::DeleteSecurityPackages($PackageName)\n\n    if($SUCCESS -eq 0)\n    {\n        throw \"DeleteSecurityPackage Error: $($SUCCESS)\"\n    }\n}\n\nfunction EnumerateSecurityPackages\n{\n    <#\n    .SYNOPSIS\n\n    The EnumerateSecurityPackages function returns an array of SecPkgInfo structures that provide information about the security packages available to the client.\n\n    .DESCRIPTION\n\n    The caller can use the Name member of a SecPkgInfo structure to specify a security package in a call to the AcquireCredentialsHandle (General) function.\n\n    .NOTES\n\n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: FreeContextBuffer (function), SecPkgInfo (Structure), SECPKG_FLAG (Enumeration)\n    Optional Dependencies: None\n\n    (func secur32 EnumerateSecurityPackages ([UInt32]) @(\n        [UInt32].MakeByRefType(), #_In_ PULONG      pcPackages\n        [IntPtr].MakeByRefType()  #_In_ PSecPkgInfo *ppPackageInfo\n    ) -EntryPoint EnumerateSecurityPackages)\n\n    .LINK\n    \n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa375397(v=vs.85).aspx\n\n    .EXAMPLE\n\n    PS > EnumerateSecurityPackages\n\n    Name         : Negotiate\n    Comment      : Microsoft Package Negotiator\n    Capabilities : INTEGRITY, PRIVACY, CONNECTION, MULTI_REQUIRED, EXTENDED_ERROR, \n                   IMPERSONATION, ACCEPT_WIN32_NAME, NEGOTIABLE, GSS_COMPATIBLE, LOGON, \n                   RESTRICTED_TOKENS, APPCONTAINER_CHECKS\n    Version      : 1\n    RpcId        : 9\n    MaxToken     : 65791\n\n    Name         : NegoExtender\n    Comment      : NegoExtender Security Package\n    Capabilities : INTEGRITY, PRIVACY, CONNECTION, IMPERSONATION, NEGOTIABLE, GSS_COMPATIBLE, \n                   LOGON, MUTUAL_AUTH, NEGO_EXTENDER, APPCONTAINER_CHECKS\n    Version      : 1\n    RpcId        : 30\n    MaxToken     : 12000\n\n    Name         : Kerberos\n    Comment      : Microsoft Kerberos V1.0\n    Capabilities : INTEGRITY, PRIVACY, TOKEN_ONLY, DATAGRAM, CONNECTION, MULTI_REQUIRED, \n                   EXTENDED_ERROR, IMPERSONATION, ACCEPT_WIN32_NAME, NEGOTIABLE, \n                   GSS_COMPATIBLE, LOGON, MUTUAL_AUTH, DELEGATION, READONLY_WITH_CHECKSUM, \n                   RESTRICTED_TOKENS, APPCONTAINER_CHECKS\n    Version      : 1\n    RpcId        : 16\n    MaxToken     : 65535\n\n    Name         : NTLM\n    Comment      : NTLM Security Package\n    Capabilities : INTEGRITY, PRIVACY, TOKEN_ONLY, CONNECTION, MULTI_REQUIRED, IMPERSONATION, \n                   ACCEPT_WIN32_NAME, NEGOTIABLE, LOGON, RESTRICTED_TOKENS, APPCONTAINER_CHECKS\n    Version      : 1\n    RpcId        : 10\n    MaxToken     : 2888\n\n    Name         : TSSSP\n    Comment      : TS Service Security Package\n    Capabilities : CONNECTION, MULTI_REQUIRED, ACCEPT_WIN32_NAME, MUTUAL_AUTH, \n                   APPCONTAINER_CHECKS\n    Version      : 1\n    RpcId        : 22\n    MaxToken     : 13000\n\n    Name         : pku2u\n    Comment      : PKU2U Security Package\n    Capabilities : INTEGRITY, PRIVACY, CONNECTION, IMPERSONATION, GSS_COMPATIBLE, MUTUAL_AUTH, \n                   NEGOTIABLE2, APPCONTAINER_CHECKS\n    Version      : 1\n    RpcId        : 31\n    MaxToken     : 12000\n\n    Name         : CloudAP\n    Comment      : Cloud AP Security Package\n    Capabilities : LOGON, NEGOTIABLE2\n    Version      : 1\n    RpcId        : 36\n    MaxToken     : 0\n\n    Name         : WDigest\n    Comment      : Digest Authentication for Windows\n    Capabilities : TOKEN_ONLY, IMPERSONATION, ACCEPT_WIN32_NAME, APPCONTAINER_CHECKS\n    Version      : 1\n    RpcId        : 21\n    MaxToken     : 4096\n\n    Name         : Schannel\n    Comment      : Schannel Security Package\n    Capabilities : INTEGRITY, PRIVACY, CONNECTION, MULTI_REQUIRED, EXTENDED_ERROR, \n                   IMPERSONATION, ACCEPT_WIN32_NAME, STREAM, MUTUAL_AUTH, \n                   APPCONTAINER_PASSTHROUGH\n    Version      : 1\n    RpcId        : 14\n    MaxToken     : 24576\n\n    Name         : Microsoft Unified Security Protocol Provider\n    Comment      : Schannel Security Package\n    Capabilities : INTEGRITY, PRIVACY, CONNECTION, MULTI_REQUIRED, EXTENDED_ERROR, \n                   IMPERSONATION, ACCEPT_WIN32_NAME, STREAM, MUTUAL_AUTH, \n                   APPCONTAINER_PASSTHROUGH\n    Version      : 1\n    RpcId        : 14\n    MaxToken     : 24576\n\n    Name         : CREDSSP\n    Comment      : Microsoft CredSSP Security Provider\n    Capabilities : INTEGRITY, PRIVACY, CONNECTION, MULTI_REQUIRED, IMPERSONATION, \n                   ACCEPT_WIN32_NAME, STREAM, MUTUAL_AUTH, APPCONTAINER_CHECKS\n    Version      : 1\n    RpcId        : 65535\n    MaxToken     : 90567\n    #>\n\n    $PackageCount = 0\n    $PackageInfo = [IntPtr]::Zero\n\n    $SUCCESS = $Secur32::EnumerateSecurityPackages([ref]$PackageCount, [ref]$PackageInfo)\n\n    if($SUCCESS -ne 0)\n    {\n        throw \"EnumerateSecurityPackages Error: $($SUCCESS)\"\n    }\n\n    for($i = 0; $i -lt $PackageCount; $i++)\n    {\n        $PackagePtr = [IntPtr]($PackageInfo.ToInt64() + ($SecPkgInfo::GetSize() * $i))\n\n        $Package = $PackagePtr -as $SecPkgInfo\n        \n        $obj = New-Object -TypeName psobject\n        $obj | Add-Member -MemberType NoteProperty -Name Name -Value ([System.Runtime.InteropServices.Marshal]::PtrToStringAuto($Package.Name))\n        $obj | Add-Member -MemberType NoteProperty -Name Comment -Value ([System.Runtime.InteropServices.Marshal]::PtrToStringAuto($Package.Comment))\n        $obj | Add-Member -MemberType NoteProperty -Name Capabilities -Value $Package.Capabilities\n        $obj | Add-Member -MemberType NoteProperty -Name Version -Value $Package.Version\n        $obj | Add-Member -MemberType NoteProperty -Name RpcId -Value $Package.RPCID\n        $obj | Add-Member -MemberType NoteProperty -Name MaxToken -Value $Package.MaxToken\n\n        Write-Output $obj\n    }\n\n    FreeContextBuffer -Buffer $PackageInfo\n}\n\nfunction FreeContextBuffer\n{\n    <#\n    .SYNOPSIS\n\n    The FreeContextBuffer function enables callers of security package functions to free memory buffers allocated by the security package.\n\n    .DESCRIPTION\n\n    Memory buffers are typically allocated by the InitializeSecurityContext (General) and AcceptSecurityContext (General) functions.\n    \n    The FreeContextBuffer function can free any memory allocated by a security package.\n\n    .PARAMETER Buffer\n\n    A pointer to memory to be freed.\n\n    .NOTES\n    \n    Author: Jared Atkinson (@jaredcatkinson)\n    License: BSD 3-Clause\n    Required Dependencies: None\n    Optional Dependencies: None\n\n    (func secur32 FreeContextBuffer ([UInt32]) @(\n          [IntPtr] #_In_ PVOID pvContextBuffer\n    ) -EntryPoint FreeContextBuffer)\n\n    .LINK\n\n    https://msdn.microsoft.com/en-us/library/windows/desktop/aa375416(v=vs.85).aspx\n\n    .EXAMPLE\n\n    PS > $PackageCount = 0\n    PS > $PackageInfo = [IntPtr]::Zero\n\n    PS > $SUCCESS = $Secur32::EnumerateSecurityPackages([ref]$PackageCount, [ref]$PackageInfo)\n\n    #\n    # Do Stuff ...\n    #\n\n    PS > FreeContextBuffer -Buffer $PackageInfo\n    #>\n\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [IntPtr]\n        $Buffer\n    )\n\n    $SUCCESS = $Secur32::FreeContextBuffer($Buffer)\n\n    if($SUCCESS -ne 0)\n    {\n        throw \"FreeContextBuffer Error: $($SUCCESS)\"\n    }\n}\n\nStart-AceScript -Uri https://10.182.18.200 -SweepId $args[0] -ScanId ([Guid]::NewGuid()) -RoutingKey siem -Thumbprint 8D1DB3B7B85B6F9E9DE87B291DF66692A10240AE"
  },
  {
    "path": "ACE-Management/PS-ACE/Scripts/ACE_Get-SimpleNamedPipe.ps1",
    "content": "﻿function Start-AceScript\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $SweepId,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $ScanId,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $RoutingKey,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Thumbprint\n    )\n\n    $HostFQDN = Get-WmiObject Win32_ComputerSystem -Property 'Name','Domain' | ForEach-Object {\"$($_.Name).$($_.Domain)\"}\n    $ResultDate = (Get-Date).ToString(\"yyyyMMddThhmmssmsmsZ\")\n\n    $dataList = New-Object -TypeName System.Collections.Generic.List['string']\n\n    foreach($o in (Get-SimpleNamedPipe -ReturnHashtables))\n    {\n        $o.Add('ComputerName', $HostFQDN)\n        $o.Add('ScanType', 'SimpleNamedPipe')\n        $o.Add('SweepId', $SweepId)\n        $o.Add('ScanId', $ScanId)\n        $o.Add('ResultDate', $ResultDate)\n\n        $message = ConvertTo-JsonV2 -InputObject $o\n        $dataList.Add($message)\n    }\n\n    $props = @{\n        ComputerName = $HostFQDN\n        ScanType     = 'SimpleNamedPipe'\n        RoutingKey   = $RoutingKey\n        ResultDate   = $ResultDate\n        ScanId       = $ScanId\n        Data         = $dataList.ToArray()\n    }\n\n    $body = (ConvertTo-JsonV2 -InputObject $props)\n\n    Write-Host $body\n\n    Invoke-AceWebRequest -Thumbprint $Thumbprint -Uri \"$($Uri)/ace/result/$($SweepId)\" -Body $body\n}\n\nfunction ConvertTo-JsonV2 \n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        $InputObject\n    )\n\n    Begin \n    {\n        $null = [System.Reflection.Assembly]::LoadWithPartialName(\"System.Web.Extensions\")\n        $Serializer = New-Object System.Web.Script.Serialization.JavaScriptSerializer\n    }\n\n    Process \n    {\n        try \n        {\n            $Serializer.Serialize($InputObject)\n        } \n        catch \n        {\n            Write-Error $_\n        }    \n    }\n}\n\nfunction Invoke-AceWebRequest\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Thumbprint,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Body\n    )\n\n    [Net.ServicePointManager]::ServerCertificateValidationCallback = {\n        $Thumbprint = $Thumbprint\n        $certificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]$args[1]\n    \n        if ($certificate -eq $null)\n        {\n            $Host.UI.WriteErrorLine(\"Null certificate.\")\n            return $true\n        }\n    \n        if ($certificate.Thumbprint -eq $Thumbprint)\n        {\n            return $true\n        }\n        else\n        {\n            $Host.UI.WriteErrorLine(\"Thumbprint mismatch. Certificate thumbprint $($certificate.Thumbprint)\")\n        }\n    \n        return $false\n    }\n\n    try\n    {\n        Write-Host \"URI: $($Uri)\"\n\n        # Create web request\n        $WebRequest = [Net.WebRequest]::Create($uri)\n        $WebRequest.Method = 'Post'\n        $WebRequest.ContentType = 'application/json'\n        $WebRequest.Headers.Add('X-API-Version:1.0')\n\n        $byteArray = [System.Text.Encoding]::UTF8.GetBytes($Body)\n        $Webrequest.ContentLength = $byteArray.Length\n        \n        $dataStream = $Webrequest.GetRequestStream()            \n        $dataStream.Write($byteArray, 0, $byteArray.Length)\n        $dataStream.Close()\n\n        # Get response stream\n        $ResponseStream = $Webrequest.GetResponse().GetResponseStream()\n    \n        # Create a stream reader and read the stream returning the string value.\n        $StreamReader = New-Object System.IO.StreamReader -ArgumentList $ResponseStream\n        $StreamReader.ReadToEnd()\n    }\n    catch\n    {\n        Write-Error \"Failed: $($_.exception.innerexception.message)\"\n    }\n}\n\nfunction Get-SimpleNamedPipe { \n<#\n    .SYNOPSIS\n\n        Gets a list of open named pipes.\n\n        Author: Greg Zakharov\n        License: \n        Required Dependencies: None\n        Optional Dependencies: None\n\n    .DESCRIPTION\n\n        When defining custom enums, structs, and unmanaged functions, it is\n        necessary to associate to an assembly module. This helper function\n        creates an in-memory module that can be passed to the 'enum',\n        'struct', and Add-Win32Type functions.\n#>\n    [CmdletBinding()]\n    Param (\n        [switch]\n        $ReturnHashtables\n    )\n\n    Begin \n    {\n        $Mscorlib = [AppDomain]::CurrentDomain.GetAssemblies() | ? { \n            $_.ManifestModule.ScopeName.Equals('CommonLanguageRuntimeLibrary') \n        } \n     \n        $SafeFindHandle = $Mscorlib.GetType('Microsoft.Win32.SafeHandles.SafeFindHandle') \n        $Win32Native = $Mscorlib.GetType('Microsoft.Win32.Win32Native') \n     \n        $WIN32_FIND_DATA = $Win32Native.GetNestedType( \n            'WIN32_FIND_DATA', [Reflection.BindingFlags]32 \n        ) \n        $FindFirstFile = $Win32Native.GetMethod( \n            'FindFirstFile', [Reflection.BindingFlags]40, \n            $null, @([String], $WIN32_FIND_DATA), $null \n        ) \n        $FindNextFile = $Win32Native.GetMethod('FindNextFile', [Reflection.BindingFlags]40, $null, @($SafeFindHandle, $WIN32_FIND_DATA), $null) \n     \n        $Obj = $WIN32_FIND_DATA.GetConstructors()[0].Invoke($null)\n        function Read-Field([String]$Field) { \n            return $WIN32_FIND_DATA.GetField($Field, [Reflection.BindingFlags]36).GetValue($Obj)\n        } \n    } \n\n    Process \n    { \n        $Handle = $FindFirstFile.Invoke($null, @('\\\\.\\pipe\\*', $obj))\n\n        \n        $Output = @{\n            Name = [string](Read-Field cFileName)\n            Instances = [UInt32](Read-Field nFileSizeLow)\n        }\n\n        do {\n            $Output = @{\n                Name = [string](Read-Field cFileName)\n                Instances = [UInt32](Read-Field nFileSizeLow)\n            }\n\n            if($ReturnHashtables) {\n                $Output\n            } else {\n                New-Object PSObject -Property $Output\n            }\n        } while($FindNextFile.Invoke($null, @($Handle, $obj)))\n     \n        $Handle.Close() \n    } \n\n    End \n    {\n    \n    } \n}\n\nStart-AceScript -Uri https://10.182.18.200 -SweepId $args[0] -ScanId ([Guid]::NewGuid()) -RoutingKey siem -Thumbprint 8D1DB3B7B85B6F9E9DE87B291DF66692A10240AE"
  },
  {
    "path": "ACE-Management/PS-ACE/Scripts/Invoke-MonsterWinRM.ps1",
    "content": "﻿# WinRM In Memory Deployment\nfunction Invoke-MonsterWinRM\n{\n    param\n    (\n        [Parameter()]\n        [string[]]\n        $ComputerName,\n\n        [Parameter(Mandatory = $true)]\n        [Management.Automation.PSCredential]\n        [Management.Automation.CredentialAttribute()]\n        $Credential,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $ScriptPath,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Thumbprint,\n\n        [Parameter()]\n        [ValidateSet('All','AccessToken','ArpCache','AtomTable','InjectedThread','KerberosTicket','LogonSession','MasterBootRecord','NetworkConnection','FullProcess','ScheduledTask','SecurityPackage','FullService','SimpleNamedPipe')]\n        [string[]]\n        $ScanType = 'All'\n    )\n\n    $scriptblock = {\n        param\n        (\n            [Parameter(Mandatory = $true)]\n            [guid]\n            $SweepId,\n\n            [Parameter(Mandatory = $true)]\n            [string]\n            $Uri,\n\n            [Parameter(Mandatory = $true)]\n            [string]\n            $ScriptPath,\n\n            [Parameter(Mandatory = $true)]\n            [string]\n            $Thumbprint,\n\n            [Parameter()]\n            [ValidateSet('All','AccessToken','ArpCache','AtomTable','InjectedThread','KerberosTicket','LogonSession','MasterBootRecord','NetworkConnection','FullProcess','ScheduledTask','SecurityPackage','FullService','SimpleNamedPipe')]\n            [string[]]\n            $ScanType = 'All'\n        )\n\n        function Invoke-AceWebRequest\n        {\n            param\n            (\n                [Parameter(Mandatory = $true)]\n                [string]\n                $Uri,\n\n                [Parameter(Mandatory = $true)]\n                [string]\n                $ApiKey,\n\n                [Parameter(Mandatory)]\n                [string]\n                $Thumbprint,\n\n                [Parameter()]\n                [ValidateSet('Delete','Get','Post','Put')]\n                [string]\n                $Method = 'Get',\n\n                [Parameter()]\n                [string]\n                $ContentType = 'application/json',\n\n                [Parameter()]\n                [string]\n                $Body\n            )\n            try\n            {\n                # Create web request\n                $WebRequest = [System.Net.WebRequest]::Create($Uri)\n    \n                $WebRequest.Headers.Add('X-API-Version:1.0')\n                $webrequest.Headers.Add(\"X-ApiKey:$($ApiKey)\")\n\n                $WebRequest.Method = $Method\n                $WebRequest.ContentType = $ContentType\n\n                # Set the callback to check for null certificate and thumbprint matching.\n                $WebRequest.ServerCertificateValidationCallback = {\n            \n                    $certificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]$args[1]\n            \n                    if ($certificate -eq $null)\n                    {\n                        $Host.UI.WriteWarningLine(\"Null certificate.\")\n                        return $true\n                    }\n    \n                    if ($certificate.Thumbprint -eq $Thumbprint)\n                    {\n                        return $true\n                    }\n                    else\n                    {\n                        $Host.UI.WriteWarningLine(\"Thumbprint mismatch. Certificate thumbprint $($certificate.Thumbprint)\")\n                        $Host.UI.WriteWarningLine(\"   Expected thumbprint: $($Thumbprint)\")\n                        $Host.UI.WriteWarningLine(\"   Received thumbprint: $($certificate.Thumbprint)\")\n                    }\n    \n                    return $false\n                }\n\n                if($PSBoundParameters.ContainsKey('Body'))\n                {\n                    $byteArray = [System.Text.Encoding]::UTF8.GetBytes($Body)\n                    $Webrequest.ContentLength = $byteArray.Length\n            \n                    $dataStream = $Webrequest.GetRequestStream()            \n                    $dataStream.Write($byteArray, 0, $byteArray.Length)\n                    $dataStream.Close()\n                }\n\n                # Get response stream\n                $ResponseStream = $webrequest.GetResponse().GetResponseStream()\n    \n                # Create a stream reader and read the stream returning the string value.\n                $StreamReader = New-Object System.IO.StreamReader -ArgumentList $ResponseStream\n                $StreamReader.ReadToEnd()\n\n                $StreamReader.Close()\n                $ResponseStream.Close()\n            }\n            catch\n            {\n                Write-Error \"Failed: $($_.exception.innerexception.message)\"\n            }\n        }\n\n        try\n        {\n            $MasterScript = Invoke-AceWebRequest -Uri \"$($Uri)$($ScriptPath)\" -Thumbprint $Thumbprint -ApiKey 1\n            Invoke-Expression -Command $MasterScript\n            Start-AceScript -Uri $Uri -SweepId $SweepId -ScanId ([Guid]::NewGuid()) -Thumbprint $Thumbprint -ScanType $ScanType\n            Write-Host -NoNewline -ForegroundColor Green -Object \"[+] \"\n            Write-Host $env:COMPUTERNAME\n        }\n        catch\n        {\n            Write-Host -NoNewline -ForegroundColor Red -Object \"[-] \"\n            Write-Host $env:COMPUTERNAME\n        }\n    }\n\n    $SweepId = [Guid]::NewGuid()\n    Invoke-Command -ComputerName $ComputerName -Credential $Credential -ScriptBlock $scriptblock -ArgumentList @($SweepId, $Uri, $ScriptPath, $Thumbprint, $ScanType) -SessionOption (New-PSSessionOption -NoMachineProfile)\n}"
  },
  {
    "path": "ACE-Management/PS-ACE/Working/ACE_Get-PSIPrefetch.ps1",
    "content": "﻿function Start-AceScript\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $SweepId,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $ScanId,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $RoutingKey,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Thumbprint\n    )\n\n    $HostFQDN = Get-WmiObject Win32_ComputerSystem -Property 'Name','Domain' | ForEach-Object {\"$($_.Name).$($_.Domain)\"}\n    $ResultDate = (Get-Date).ToString(\"yyyyMMddThhmmssmsmsZ\")\n\n    $dataList = New-Object -TypeName System.Collections.Generic.List['string']\n\n    foreach($o in (Get-PSIPrefetch -ReturnHashtables))\n    {\n        $o.Add('ComputerName', $HostFQDN)\n        $o.Add('ScanType', 'Prefetch')\n        $o.Add('SweepId', $SweepId)\n        $o.Add('ScanId', $ScanId)\n        $o.Add('ResultDate', $ResultDate)\n\n        $message = ConvertTo-JsonV2 -InputObject $o\n        $dataList.Add($message)\n    }\n\n    $props = @{\n        ComputerName = $HostFQDN\n        ScanType     = 'Prefetch'\n        RoutingKey   = $RoutingKey\n        ResultDate   = $ResultDate\n        ScanId       = $ScanId\n        Data         = $dataList.ToArray()\n    }\n\n    $body = (ConvertTo-JsonV2 -InputObject $props)\n\n    Write-Host $body\n\n    #Invoke-AceWebRequest -Thumbprint $Thumbprint -Uri \"$($Uri)/ace/result/$($SweepId)\" -Body $body\n}\n\nfunction ConvertTo-JsonV2 \n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        $InputObject\n    )\n\n    Begin \n    {\n        $null = [System.Reflection.Assembly]::LoadWithPartialName(\"System.Web.Extensions\")\n        $Serializer = New-Object System.Web.Script.Serialization.JavaScriptSerializer\n    }\n\n    Process \n    {\n        try \n        {\n            $Serializer.Serialize($InputObject)\n        } \n        catch \n        {\n            Write-Error $_\n        }    \n    }\n}\n\nfunction Invoke-AceWebRequest\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Thumbprint,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Body\n    )\n\n    [Net.ServicePointManager]::ServerCertificateValidationCallback = {\n        $Thumbprint = $Thumbprint\n        $certificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]$args[1]\n    \n        if ($certificate -eq $null)\n        {\n            $Host.UI.WriteErrorLine(\"Null certificate.\")\n            return $true\n        }\n    \n        if ($certificate.Thumbprint -eq $Thumbprint)\n        {\n            return $true\n        }\n        else\n        {\n            $Host.UI.WriteErrorLine(\"Thumbprint mismatch. Certificate thumbprint $($certificate.Thumbprint)\")\n        }\n    \n        return $false\n    }\n\n    try\n    {\n        Write-Host \"URI: $($Uri)\"\n\n        # Create web request\n        $WebRequest = [Net.WebRequest]::Create($uri)\n        $WebRequest.Method = 'Post'\n        $WebRequest.ContentType = 'application/json'\n        $WebRequest.Headers.Add('X-API-Version:1.0')\n\n        $byteArray = [System.Text.Encoding]::UTF8.GetBytes($Body)\n        $Webrequest.ContentLength = $byteArray.Length\n        \n        $dataStream = $Webrequest.GetRequestStream()            \n        $dataStream.Write($byteArray, 0, $byteArray.Length)\n        $dataStream.Close()\n\n        # Get response stream\n        $ResponseStream = $Webrequest.GetResponse().GetResponseStream()\n    \n        # Create a stream reader and read the stream returning the string value.\n        $StreamReader = New-Object System.IO.StreamReader -ArgumentList $ResponseStream\n        $StreamReader.ReadToEnd()\n    }\n    catch\n    {\n        Write-Error \"Failed: $($_.exception.innerexception.message)\"\n    }\n}\n\nfunction Get-PSIPrefetch {\n<#\n    .SYNOPSIS\n\n        Return prefetch file information.\n\n        Author: Jared Atkinson, Lee Christensen (@tifkin_)\n        License: BSD 3-Clause\n        Required Dependencies: None\n        Optional Dependencies: None\n\n#>\n\n    [CmdletBinding()]\n    param\n    (\n        [Parameter()]\n        [string]\n        $Path,\n\n        [switch]\n        $ReturnHashtables\n    )\n\n    begin\n    {\n        if($PSBoundParameters.ContainsKey('Path'))\n        {\n            $props = @{FullName = $Path}\n            $files = New-Object -TypeName psobject -Property $props\n        }\n        else\n        {\n            $files = Get-ChildItem -Path C:\\Windows\\Prefetch\\* -Include *.pf\n        }\n    }\n\n    process\n    {\n        foreach($file in $files)\n        {\n            $bytes = Get-Content -Path $file.FullName -Encoding Byte\n        \n            # Check for Prefetch file header 'SCCA'\n            if([System.Text.Encoding]::ASCII.GetString($bytes[4..7]) -eq 'SCCA')\n            {\n                $Version = $bytes[0]\n            \n                switch($Version)\n                {\n                    0x11 # Windows XP\n                    {\n                        $AccessTimeBytes = $bytes[0x78..0x7F]\n                        $RunCount = [BitConverter]::ToInt32($bytes, 0x90)\n                    }\n                    0x17 # Windows 7\n                    {\n                        $AccessTimeBytes = $bytes[0x80..0x87]\n                        $RunCount = [BitConverter]::ToInt32($bytes, 0x98);\n                    }\n                    0x1A # Windows 8\n                    {\n                        $AccessTimeBytes = $bytes[0x80..0xBF]\n                        $RunCount = [BitConverter]::ToInt32($bytes, 0xD0);\n                    }\n                }\n            \n                $Name = [Text.Encoding]::Unicode.GetString($bytes, 0x10, 0x3C).Split('\\0')[0].TrimEnd(\"`0\")\n                $PathHash = [BitConverter]::ToString($bytes[0x4f..0x4c]).Replace(\"-\",\"\")\n                $DeviceCount = [BitConverter]::ToInt32($bytes, 0x70)\n                $DependencyString = [Text.Encoding]::Unicode.GetString($bytes, [BitConverter]::ToInt32($bytes, 0x64), [BitConverter]::ToInt32($bytes, 0x68)).Replace(\"`0\",';').TrimEnd(';')\n                $Dependencies = $DependencyString.Split(';')\n                $Path = $Dependencies | Where-Object {$_ -like \"*$($Name)\"}\n                $DependencyCount = $Dependencies.Length\n\n                for($i = 0; $i -lt $AccessTimeBytes.Length; $i += 8)\n                {\n                    $Props = @{\n                        Name = $Name\n                        Path = $Path\n                        PathHash = $PathHash\n                        DependencyCount = $DependencyCount\n                        PrefetchAccessTime = [DateTime]::FromFileTimeUtc([BitConverter]::ToInt64($AccessTimeBytes, $i))\n                        DeviceCount = $DeviceCount\n                        RunCount = $RunCount\n                        DependencyFiles = $DependencyString\n                    }\n\n                    if($ReturnHashtables) {\n                        $Props\n                    } else {\n                        New-Object -TypeName psobject -Property $Props\n                    }\n                }\n            }\n        }\n    }\n\n    end\n    {\n\n    }\n}"
  },
  {
    "path": "ACE-WebService/.gitignore",
    "content": "﻿# Download this file using PowerShell v3 under Windows with the following comand:\n# Invoke-WebRequest https://gist.githubusercontent.com/kmorcinek/2710267/raw/ -OutFile .gitignore\n# or wget:\n# wget --no-check-certificate http://gist.githubusercontent.com/kmorcinek/2710267/raw/.gitignore\n\n# User-specific files\n*.suo\n*.user\n*.sln.docstates\n\n# Build results\n\n[Dd]ebug/\n[Rr]elease/\nx64/\nbuild/\n[Bb]in/\n[Oo]bj/\n\n# NuGet Packages\n*.nupkg\n# The packages folder can be ignored because of Package Restore\n**/packages/*\n# except build/, which is used as an MSBuild target.\n!**/packages/build/\n# Uncomment if necessary however generally it will be regenerated when needed\n#!**/packages/repositories.config\n\n# MSTest test Results\n[Tt]est[Rr]esult*/\n[Bb]uild[Ll]og.*\n\n*_i.c\n*_p.c\n*.ilk\n*.meta\n*.obj\n*.pch\n*.pdb\n*.pgc\n*.pgd\n*.rsp\n*.sbr\n*.tlb\n*.tli\n*.tlh\n*.tmp\n*.tmp_proj\n*.log\n*.vspscc\n*.vssscc\n.builds\n*.pidb\n*.log\n*.scc\n\n# OS generated files #\n.DS_Store*\nIcon?\n\n# Visual C++ cache files\nipch/\n*.aps\n*.ncb\n*.opensdf\n*.sdf\n*.cachefile\n\n# Visual Studio profiler\n*.psess\n*.vsp\n*.vspx\n\n# Guidance Automation Toolkit\n*.gpState\n\n# ReSharper is a .NET coding add-in\n_ReSharper*/\n*.[Rr]e[Ss]harper\n\n# TeamCity is a build add-in\n_TeamCity*\n\n# DotCover is a Code Coverage Tool\n*.dotCover\n\n# NCrunch\n*.ncrunch*\n.*crunch*.local.xml\n\n# Installshield output folder\n[Ee]xpress/\n\n# DocProject is a documentation generator add-in\nDocProject/buildhelp/\nDocProject/Help/*.HxT\nDocProject/Help/*.HxC\nDocProject/Help/*.hhc\nDocProject/Help/*.hhk\nDocProject/Help/*.hhp\nDocProject/Help/Html2\nDocProject/Help/html\n\n# Click-Once directory\npublish/\n\n# Publish Web Output\n*.Publish.xml\n\n# Windows Azure Build Output\ncsx\n*.build.csdef\n\n# Windows Store app package directory\nAppPackages/\n\n# Others\n*.Cache\nClientBin/\n[Ss]tyle[Cc]op.*\n~$*\n*~\n*.dbmdl\n*.[Pp]ublish.xml\n*.pfx\n*.publishsettings\nmodulesbin/\ntempbin/\n\n# EPiServer Site file (VPP)\nAppData/\n\n# RIA/Silverlight projects\nGenerated_Code/\n\n# Backup & report files from converting an old project file to a newer\n# Visual Studio version. Backup files are not needed, because we have git ;-)\n_UpgradeReport_Files/\nBackup*/\nUpgradeLog*.XML\nUpgradeLog*.htm\n\n# vim\n*.txt~\n*.swp\n*.swo\n \n# svn\n.svn\n\n# Remainings from resolvings conflicts in Source Control\n*.orig\n\n# SQL Server files\n**/App_Data/*.mdf\n**/App_Data/*.ldf\n**/App_Data/*.sdf\n\n\n#LightSwitch generated files\nGeneratedArtifacts/\n_Pvt_Extensions/\nModelManifest.xml\n\n# =========================\n# Windows detritus\n# =========================\n\n# Windows image file caches\nThumbs.db\nehthumbs.db\n\n# Folder config file\nDesktop.ini\n\n# Recycle Bin used on file shares\n$RECYCLE.BIN/\n\n# Mac desktop service store files\n.DS_Store\n\n# SASS Compiler cache\n.sass-cache\n\n# Visual Studio 2014 CTP\n**/*.sln.ide\n\n# Visual Studio temp something\n.vs/\n\n# VS 2015+\n*.vc.vc.opendb\n*.vc.db\n\n# Rider\n.idea/\n\n# Output folder used by Webpack or other FE stuff\n**/node_modules/*\n**/wwwroot/*\n\n# SpecFlow specific\n*.feature.cs\n*.feature.xlsx.*\n*.Specs_*.html\n\n#####\n# End of core ignore list, below put you custom 'per project' settings (patterns or path)\n#####"
  },
  {
    "path": "ACE-WebService/ACEWebService.sln",
    "content": "﻿\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 15\nVisualStudioVersion = 15.0.26430.16\nMinimumVisualStudioVersion = 10.0.40219.1\nProject(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"Solution Items\", \"Solution Items\", \"{D1B5F438-8ADC-4742-B3C9-D581E2A35763}\"\nEndProject\nProject(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"ACEWebService\", \"src\\ACEWebService\\ACEWebService.csproj\", \"{2794F6A8-A327-40BD-A11F-F72ECDBD2273}\"\nEndProject\nGlobal\n\tGlobalSection(SolutionConfigurationPlatforms) = preSolution\n\t\tDebug|Any CPU = Debug|Any CPU\n\t\tRelease|Any CPU = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(ProjectConfigurationPlatforms) = postSolution\n\t\t{2794F6A8-A327-40BD-A11F-F72ECDBD2273}.Debug|Any CPU.ActiveCfg = Debug|Any CPU\n\t\t{2794F6A8-A327-40BD-A11F-F72ECDBD2273}.Debug|Any CPU.Build.0 = Debug|Any CPU\n\t\t{2794F6A8-A327-40BD-A11F-F72ECDBD2273}.Release|Any CPU.ActiveCfg = Release|Any CPU\n\t\t{2794F6A8-A327-40BD-A11F-F72ECDBD2273}.Release|Any CPU.Build.0 = Release|Any CPU\n\tEndGlobalSection\n\tGlobalSection(SolutionProperties) = preSolution\n\t\tHideSolutionNode = FALSE\n\tEndGlobalSection\nEndGlobal\n"
  },
  {
    "path": "ACE-WebService/Configure-AceWebService.ps1",
    "content": "﻿function Configure-AceWebService\n{\n    param\n    (\n        [Parameter()]\n        [string]\n        $FilePath = 'C:\\Windows\\Temp'\n    )\n\n    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12\n    \n    # Download ACEWebService latest release\n    Invoke-WebRequest -Uri https://github.com/Invoke-IR/ACE/releases/download/test/ACEWebService.zip -OutFile \"$($FilePath)\\ACEWebService.zip\"\n    Expand-Archive -Path \"$($FilePath)\\ACEWebService.zip\" -DestinationPath $FilePath\n    \n    # Download standalone .NET Core\n    Invoke-WebRequest -Uri https://dotnetcli.azureedge.net/dotnet/Runtime/2.0.5/dotnet-runtime-2.0.5-win-x64.zip -OutFile \"$($FilePath)\\dotnet.zip\"\n    Expand-Archive -Path \"$($FilePath)\\dotnet.zip\" -DestinationPath \"$($FilePath)\\ACEWebService\\dotnet\"\n    \n    # Cleanup Downloads\n    Remove-Item -Path \"$($FilePath)\\dotnet.zip\"\n    Remove-Item -Path \"$($FilePath)\\ACEWebService.zip\"\n    \n    # Create appsettings.Production.json file\n    $appsettings = New-AppSettingsJson\n    $appsettings | Out-File -FilePath \"$($FilePath)\\ACEWebService\\appsettings.Production.json\" -Force\n\n    # Allow port 80 through the firewall\n    $null = New-NetFirewallRule -DisplayName '[ACE] HTTP Inbound' -Profile @('Domain', 'Private', 'Public') -Direction Inbound -Action Allow -Protocol TCP -LocalPort @('80')\n    \n    # Setup portforward\n    netsh interface portproxy add v4tov4 listenaddress=* listenport=80 connectaddress=127.0.0.1 connectport=5000\n\n    # Start and configure WinRM\n    Start-Service -Name WinRM\n    Set-Item -Path WSMan:\\localhost\\Client\\TrustedHosts -Value * -Force\n\n    # Change directories to ACEWebService directory\n    Set-Location \"$($FilePath)\\ACEWebService\"\n}\n\nfunction New-AppSettingsJson\n{\n    $RabbitMQServer = Read-Host -Prompt RabbitMQServer\n    $RabbitMQUser = Read-Host -Prompt RabbitMQUser\n    $RabbitMQPassword = Read-Host -Prompt RabbitMQPassword -AsSecureString\n    $NginxSSLThumbprint = Read-Host -Prompt Thumbprint\n    $SQLServer = Read-Host -Prompt SQLServer\n    $SQLPassword = Read-Host -Prompt SQLPassword -AsSecureString\n    $EncryptionPassphrase = Read-Host -Prompt 'Choose an encryption passphrase for the SQL Server' -AsSecureString\n\n    $RabbitMQPasswordClear = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($RabbitMQPassword))\n    $SQLPasswordClear = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($SQLPassword))\n    $EncryptionPassphraseClear = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($EncryptionPassphrase))\n\n$appsettings = @\"\n{\n  \"Logging\": {\n    \"IncludeScopes\": false,\n    \"LogLevel\": {\n      \"Default\": \"Debug\",\n      \"System\": \"Information\",\n      \"Microsoft\": \"Information\"\n    }\n  },\n\n  \"AppSettings\": {\n    \"RabbitMQServer\": \"$($RabbitMQServer)\",\n    \"RabbitMQUserName\": \"$($RabbitMQUser)\",\n    \"RabbitMQPassword\": \"$($RabbitMQPasswordClear)\",\n\t\"EncryptionPassphrase\": \"$($EncryptionPassphraseClear)\",\n    \"Thumbprint\": \"$($NginxSSLThumbprint)\"\n  },\n\n  \"ConnectionStrings\": {\n    \"DefaultConnection\": \"Server=$($SQLServer);Database=ACEWebService;User Id=sa;Password=$($SQLPasswordClear);MultipleActiveResultSets=true\"\n  }\n}\n\"@\n\n    Write-Output $appsettings\n}"
  },
  {
    "path": "ACE-WebService/NuGet.config",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n  <packageSources>\n    <add key=\"nuget.org\" value=\"https://api.nuget.org/v3/index.json\" />\n    <add key=\"aspnet-contrib\" value=\"https://www.myget.org/F/aspnet-contrib/api/v3/index.json\" />\n    <add key=\"dotnet-core\" value=\"https://dotnet.myget.org/F/dotnet-core/api/v3/index.json\" />\n    <add key=\"powershell-core\" value=\"https://powershell.myget.org/F/powershell-core/api/v3/index.json\" />    \n  </packageSources>\n</configuration>"
  },
  {
    "path": "ACE-WebService/dockerfile",
    "content": "FROM microsoft/aspnetcore-build AS builder\nWORKDIR /source\nCOPY *.csproj .\nCOPY nuget.config .\nRUN dotnet restore\nCOPY . .\nRUN dotnet publish --output /ace/ --configuration Release\n\nFROM microsoft/aspnetcore\nWORKDIR /ace\nCOPY --from=builder /ace .\nENTRYPOINT [\"dotnet\", \"ACEWebService.dll\"]"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/ACEWebService.csproj",
    "content": "﻿<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n\n  <PropertyGroup>\n    <TargetFramework>netcoreapp2.0</TargetFramework>\n    <PreserveCompilationContext>true</PreserveCompilationContext>\n    <AssemblyName>ACEWebService</AssemblyName>\n    <OutputType>exe</OutputType>\n    <PackageId>ACEWebService</PackageId>\n    <RuntimeFrameworkVersion>2.0.0</RuntimeFrameworkVersion>\n    <RuntimeIdentifiers>win10-x64;debian.8-x64</RuntimeIdentifiers>\n  </PropertyGroup>\n\n  <PropertyGroup Condition=\"'$(Configuration)|$(Platform)'=='Release|AnyCPU'\">\n    <PlatformTarget>AnyCPU</PlatformTarget>\n  </PropertyGroup>\n\n  <ItemGroup>\n    <None Include=\"App.config\" />\n    <None Update=\"wwwroot\\**\\*;scripts\\**\\*\">\n      <CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>\n    </None>\n  </ItemGroup>\n\n  <ItemGroup>\n    <PackageReference Include=\"Microsoft.AspNetCore.Diagnostics\" Version=\"1.1.1\" />\n    <PackageReference Include=\"Microsoft.AspNetCore.Mvc\" Version=\"1.0.3\" />\n    <PackageReference Include=\"Microsoft.AspNetCore.Mvc.Versioning\" Version=\"1.0.3\" />\n    <PackageReference Include=\"Microsoft.AspNetCore.Routing\" Version=\"1.0.3\" />\n    <PackageReference Include=\"Microsoft.AspNetCore.Server.IISIntegration\" Version=\"1.0.2\" />\n    <PackageReference Include=\"Microsoft.AspNetCore.Server.Kestrel\" Version=\"1.0.3\" />\n    <PackageReference Include=\"Microsoft.AspNetCore.StaticFiles\" Version=\"1.1.1\" />\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.InMemory\" Version=\"1.0.3\" />\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.SqlServer\" Version=\"1.0.3\" />\n    <PackageReference Include=\"Microsoft.EntityFrameworkCore.Tools\" Version=\"1.0.0\">\n      <PrivateAssets>All</PrivateAssets>\n    </PackageReference>\n    <PackageReference Include=\"Microsoft.Extensions.Configuration.EnvironmentVariables\" Version=\"1.0.2\" />\n    <PackageReference Include=\"Microsoft.Extensions.Configuration.FileExtensions\" Version=\"1.0.2\" />\n    <PackageReference Include=\"Microsoft.Extensions.Configuration.Json\" Version=\"1.0.2\" />\n    <PackageReference Include=\"Microsoft.Extensions.Logging\" Version=\"1.0.2\" />\n    <PackageReference Include=\"Microsoft.Extensions.Logging.Console\" Version=\"1.0.2\" />\n    <PackageReference Include=\"Microsoft.Extensions.Logging.Debug\" Version=\"1.0.2\" />\n    <PackageReference Include=\"Microsoft.Extensions.Options.ConfigurationExtensions\" Version=\"1.0.2\" />\n    <PackageReference Include=\"Microsoft.Management.Infrastructure\" Version=\"1.0.0-alpha*\" />\n    <PackageReference Include=\"Novell.Directory.Ldap.NETStandard\" Version=\"2.3.7\" />\n    <PackageReference Include=\"quartz\" Version=\"3.0.0-alpha3\" />\n    <PackageReference Include=\"RabbitMQ.Client\" Version=\"4.1.1\" />\n    <PackageReference Include=\"SSH.NET\" Version=\"2016.0.0\" />\n  </ItemGroup>\n\n  <ItemGroup>\n    <DotNetCliToolReference Include=\"Microsoft.EntityFrameworkCore.Tools.DotNet\" Version=\"1.0.0\" />\n  </ItemGroup>\n\n</Project>\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/App.config",
    "content": "﻿<configuration>\n   <runtime>\n      <gcServer enabled=\"true\"/>\n   </runtime>\n</configuration>\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/AppSettings.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\n\nnamespace ACEWebService\n{\n    public class AppSettings\n    {\n        public string RabbitMQServer { get; set; }\n        public string RabbitMQUserName { get; set; }\n        public string RabbitMQPassword { get; set; }\n        public string Thumbprint { get; set; }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Controllers/ComputerController.cs",
    "content": "﻿using ACEWebService.Entities;\nusing Microsoft.AspNetCore.Authorization;\nusing Microsoft.AspNetCore.Mvc;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace ACEWebService.Controllers\n{\n    [Authorize(Policy = \"ApiKey\")]\n    [Route(\"ace/[controller]\")]\n    public class ComputerController : Controller\n    {\n        private ACEWebServiceDbContext _context;\n\n        public ComputerController(ACEWebServiceDbContext context)\n        {\n            _context = context;\n        }\n\n        [HttpGet(\"{id}\")]\n        // GET /ace/computer/{id}\n        public Computer Get([FromRoute]Guid id)\n        {\n            Computer computer = _context.Computers.SingleOrDefault(c => c.Id == id);\n            return computer;\n        }\n\n        // GET /ace/computer\n        [HttpGet()]\n        public IEnumerable<Computer> Get()\n        {\n            return _context.Computers;\n        }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Controllers/CredentialController.cs",
    "content": "﻿using ACEWebService.Entities;\nusing ACEWebService.Security;\nusing ACEWebService.Services;\nusing ACEWebService.ViewModels;\nusing Microsoft.AspNetCore.Authorization;\nusing Microsoft.AspNetCore.Mvc;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace ACEWebService.Controllers\n{\n    [Authorize(Policy = \"ApiKey\")]\n    [Route(\"ace/[controller]\")]\n    public class CredentialController : Controller\n    {\n        private ACEWebServiceDbContext _context;\n        private ICryptographyService _cryptoService;\n\n        public CredentialController(ACEWebServiceDbContext context, ICryptographyService cryptoService)\n        {\n            _context = context;\n            _cryptoService = cryptoService;\n        }\n\n        // GET /ace/credential/delete/{id}\n        [HttpGet(\"delete/{id}\")]\n        public Credential Delete([FromRoute]Guid id)\n        {\n            User requestor = _context.Users.SingleOrDefault(u => u.ApiKey == Request.Headers[\"X-ApiKey\"]);\n\n            if(requestor.IsAdmin)\n            {\n                try\n                {\n                    Credential credential = _context.Credentials.SingleOrDefault(cred => cred.Id == id);\n                    _context.Credentials.Remove(credential);\n                    _context.SaveChanges();\n                    return credential;\n                }\n                catch\n                {\n                    throw new Exception(\"Failed to delete credential\");\n                }\n            }\n            else\n            {\n                throw new Exception(\"Only administrator users can delete credentials.\");\n            }\n        }\n\n        // GET /ace/credential\n        [HttpGet()]\n        public IEnumerable<Credential> Get()\n        {\n            User requestor = _context.Users.SingleOrDefault(u => u.ApiKey == Request.Headers[\"X-ApiKey\"]);\n\n            if (requestor.IsAdmin)\n            {\n                return _context.Credentials;\n            }\n            else\n            {\n                throw new Exception(\"Only administrator users can enumerate credentials.\");\n            }\n        }\n\n        // GET /ace/credential/pscredential\n        [HttpGet(\"pscredential/{id}\")]\n        public Credential Get([FromRoute]Guid Id)\n        {\n            User requestor = _context.Users.SingleOrDefault(u => u.ApiKey == Request.Headers[\"X-ApiKey\"]);\n\n            if (requestor.IsAdmin)\n            {\n                Credential cred = _context.Credentials.SingleOrDefault(c => c.Id == Id);\n                cred.Password = _cryptoService.Decrypt(cred.Password);\n                return cred;\n\n            }\n            else\n            {\n                throw new Exception(\"Only administrator users can enumerate credentials.\");\n            }\n        }\n\n        // POST /ace/credential\n        [HttpPost()]\n        public IActionResult Post([FromBody]CredentialViewModel param)\n        {\n            User requestor = _context.Users.SingleOrDefault(u => u.ApiKey == Request.Headers[\"X-ApiKey\"]);\n\n            if (requestor.IsAdmin)\n            {\n                if (ModelState.IsValid)\n                {\n                    Credential cred = new Credential\n                    {\n                        UserName = param.UserName,\n                        Password = _cryptoService.Encrypt(param.Password)\n                    };\n                    _context.Credentials.Add(cred);\n                    _context.SaveChanges();\n                    return Ok(cred);\n                }\n                else\n                {\n                    return BadRequest(ModelState);\n                }\n            }\n            else\n            {\n                throw new Exception(\"Only administrator users can add new credentials.\");\n            }\n        }\n\n        // PUT /ace/credential/{id}\n        [HttpPut(\"{id}\")]\n        public Credential Update([FromRoute]Guid Id, [FromBody]CredentialViewModel param)\n        {\n            User requestor = _context.Users.SingleOrDefault(u => u.ApiKey == Request.Headers[\"X-ApiKey\"]);\n\n            if (requestor.IsAdmin)\n            {\n                Credential credential = _context.Credentials.SingleOrDefault(cred => cred.Id == Id);\n                credential.UserName = param.UserName;\n                credential.Password = _cryptoService.Encrypt(param.Password);\n                _context.Credentials.Update(credential);\n                _context.SaveChanges();\n                return credential;\n            }\n            else\n            {\n                throw new Exception(\"Only administrator users can update credentials.\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Controllers/DiscoverController.cs",
    "content": "﻿using ACEWebService.Services;\nusing ACEWebService.ViewModels;\nusing Microsoft.AspNetCore.Authorization;\nusing Microsoft.AspNetCore.Mvc;\nusing System;\n\nnamespace ACEWebService.Controllers\n{\n    [Authorize(Policy = \"ApiKey\")]\n    [Route(\"ace/[controller]\")]\n    public class DiscoverController : Controller\n    {\n        private IDiscoveryService _discoverService;\n        \n        public DiscoverController(IDiscoveryService discoverService)\n        {\n            _discoverService = discoverService;\n        }\n\n        /*\n        // POST /ace/discover/domain\n        [Route(\"/ace/discover/domain\")]\n        [HttpPost]\n        public IActionResult Domain([FromBody]DiscoveryActiveDirectoryViewModel param)\n        {\n            if (ModelState.IsValid)\n            {\n                _discoverService.Discover(param);\n                return Ok();\n            }\n            else\n            {\n                return BadRequest(ModelState);\n            }\n        }\n        */\n\n        // POST /ace/discover/computerlist\n        [Route(\"/ace/discover/computerlist\")]\n        [HttpPost()]\n        public IActionResult ComputerList([FromBody]DiscoveryComputerListViewModel param)\n        {\n            if (ModelState.IsValid)\n            {\n                _discoverService.Discover(param);\n                return Ok();\n            }\n            else\n            {\n                return BadRequest(ModelState);\n            }\n        }\n    }\n}"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Controllers/DownloadController.cs",
    "content": "﻿using ACEWebService.Entities;\nusing ACEWebService.Services;\nusing ACEWebService.ViewModels;\nusing Microsoft.AspNetCore.Authorization;\nusing Microsoft.AspNetCore.Mvc;\nusing System;\nusing Microsoft.AspNetCore.Hosting;\n\nnamespace ACEWebService.Controllers\n{\n    [Route(\"ace/[controller]\")]\n    public class DownloadController : Controller\n    {\n        private ACEWebServiceDbContext _context;\n        private IHostingEnvironment _hostingEnv;\n        private IDownloadService _downloadService;\n\n        public DownloadController(ACEWebServiceDbContext context, IHostingEnvironment hostingEnv, IDownloadService downloadService)\n        {\n            _context = context;\n            _hostingEnv = hostingEnv;\n            _downloadService = downloadService;\n        }\n\n        // POST /ace/download\n        [Authorize(Policy = \"ApiKey\")]\n        [HttpPost]\n        public IActionResult RequestFile([FromBody]DownloadRequestViewModel param)\n        {\n            if (ModelState.IsValid)\n            {\n                Guid Id = Guid.NewGuid();\n                _downloadService.DownloadRequest(param, Id);\n                return Ok(Id);\n            }\n            else\n            {\n                return BadRequest(ModelState);\n            }\n        }\n\n        // POST /ace/download/{id}\n        [HttpPost(\"{id}\")]\n        public IActionResult ReceiveFile([FromRoute]Guid id, [FromBody]DownloadReceiveViewModel param)\n        {\n            if (ModelState.IsValid)\n            {\n                _context.Downloads.Add(new Download{\n                    Id = id,\n                    ComputerName = param.ComputerName,\n                    Name = param.Name,\n                    FullPath = param.FullPath,\n                    Content = param.Content,\n                    DownloadTime = DateTime.UtcNow\n                });\n                _context.SaveChanges();\n\n                return Ok(param.FullPath);\n            }\n            else\n            {\n                return BadRequest(ModelState);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Controllers/ResultController.cs",
    "content": "﻿using ACEWebService.Services;\nusing ACEWebService.ViewModels;\nusing Microsoft.AspNetCore.Mvc;\nusing Microsoft.Extensions.Configuration;\nusing System;\n\nnamespace ACEWebService.Controllers\n{\n    [Route(\"ace/[controller]\")]\n    public class ResultController : Controller\n    {\n        private ISweepResultProcessorService _sweepProcessorService;\n        //IConfigurationRoot _configuration;\n\n        public ResultController(ISweepResultProcessorService sweepWriterService)\n        {\n            _sweepProcessorService = sweepWriterService;\n        }\n\n        // POST /ace/result/{scandId}\n        [HttpPost(\"{id}\")]\n        public IActionResult Post([FromRoute]Guid id, [FromBody]SweepResultViewModel result)\n        {\n            if (ModelState.IsValid)\n            {\n                _sweepProcessorService.Process(id, result);\n                return Ok();\n            }\n            else\n            {\n                return BadRequest(ModelState);\n            }\n        }\n    }\n}"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Controllers/ScanController.cs",
    "content": "﻿using ACEWebService.Entities;\nusing Microsoft.AspNetCore.Authorization;\nusing Microsoft.AspNetCore.Mvc;\nusing System;\nusing System.Linq;\n\nnamespace ACEWebService.Controllers\n{\n    [Authorize(Policy = \"ApiKey\")]\n    [Route(\"ace/[controller]\")]\n    public class ScanController : Controller\n    {\n        private ACEWebServiceDbContext _context;\n        \n        public ScanController(ACEWebServiceDbContext context)\n        {\n            _context = context;\n        }\n\n        // GET /ace/scan/{sweepId}\n        [HttpGet(\"{id}\")]\n        public IQueryable<Scan> GetSweepScans([FromRoute]Guid id)\n        {\n            return _context.Set<Scan>().Where(s => s.SweepIdentifier == id);\n        }\n\n        // POST /ace/scan/success/{id}\n        [Route(\"/ace/scan/success/{id}\")]\n        [HttpPost(\"{id}\")]\n        public IActionResult Success([FromRoute]Guid id)\n        {\n            if (ModelState.IsValid)\n            {\n                Scan scan = _context.Scans.Single(s => s.Id == id);\n                scan.StopTime = DateTime.UtcNow;\n                scan.Status = \"Completed\";\n                _context.Scans.Update(scan);\n\n                Sweep sweep = _context.Sweeps.Single(s => s.Id == scan.SweepIdentifier);\n                sweep.CompleteCount++;\n                if ((sweep.CompleteCount + sweep.ErrorCount) == sweep.ScanCount)\n                {\n                    sweep.Status = \"Completed\";\n                }\n                _context.Sweeps.Update(sweep);\n\n                _context.SaveChanges();\n\n                return Ok();\n            }\n            else\n            {\n                return BadRequest(ModelState);\n            }\n        }\n\n        // POST /ace/scan/failed/{id}\n        [Route(\"/ace/scan/failed/{id}\")]\n        [HttpPost(\"{id}\")]\n        public IActionResult Failure([FromRoute]Guid id)\n        {\n            if (ModelState.IsValid)\n            {\n                Scan scan = _context.Scans.Single(s => s.Id == id);\n                scan.StopTime = DateTime.UtcNow;\n                scan.Status = \"Failed\";\n                _context.Scans.Update(scan);\n\n                Sweep sweep = _context.Sweeps.Single(s => s.Id == scan.SweepIdentifier);\n                sweep.ErrorCount++;\n                if ((sweep.CompleteCount + sweep.ErrorCount) == sweep.ScanCount)\n                {\n                    sweep.Status = \"Completed\";\n                }\n                _context.Sweeps.Update(sweep);\n\n                _context.SaveChanges();\n\n                return Ok();\n            }\n            else\n            {\n                return BadRequest(ModelState);\n            }\n        }\n    }\n}"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Controllers/ScriptController.cs",
    "content": "﻿using ACEWebService.Entities;\nusing ACEWebService.ViewModels;\nusing Microsoft.AspNetCore.Authorization;\nusing Microsoft.AspNetCore.Http;\nusing Microsoft.AspNetCore.Mvc;\nusing System;\nusing System.IO;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Text;\nusing System.Threading.Tasks;\nusing Microsoft.AspNetCore.Hosting;\n\nnamespace ACEWebService.Controllers\n{\n    //[Authorize(Policy = \"ApiKey\")]\n    [Route(\"ace/[controller]\")]\n    public class ScriptController : Controller\n    {\n        private ACEWebServiceDbContext _context;\n        private IHostingEnvironment _hostingEnv;\n\n        public ScriptController(ACEWebServiceDbContext context, IHostingEnvironment hostingEnv)\n        {\n            _context = context;\n            _hostingEnv = hostingEnv;\n        }\n\n        // GET /ace/script/delete/{id}\n        [HttpGet(\"delete/{id}\")]\n        public Script Delete([FromRoute]Guid id)\n        {\n            User requestor = _context.Users.SingleOrDefault(u => u.ApiKey == Request.Headers[\"X-ApiKey\"]);\n\n            if (requestor.IsAdmin)\n            {\n                try\n                {\n                    Script script = _context.Scripts.SingleOrDefault(s => s.Id == id);\n\n                    // Delete the script from disk\n                    string scriptLocation = string.Format(@\"{0}\\{1}\", _hostingEnv.ContentRootPath, script.Uri);\n                    System.IO.File.Delete(scriptLocation);\n\n                    // Remove the script from the database\n                    _context.Scripts.Remove(script);\n                    _context.SaveChanges();\n                    return script;\n                }\n                catch\n                {\n                    throw new Exception(\"Failed to delete script.\");\n                }\n            }\n            else\n            {\n                throw new Exception(\"Only administrator users can delete credentials.\");\n            }\n        }\n\n        // GET /ace/script\n        [HttpGet]\n        public IEnumerable<Script> Get()\n        {\n            return _context.Scripts;\n        }\n\n        // POST /ace/script\n        [HttpPost]\n        public IActionResult Upload([FromBody]FileViewModel param)\n        {\n            User requestor = _context.Users.SingleOrDefault(u => u.ApiKey == Request.Headers[\"X-ApiKey\"]);\n\n            if (requestor.IsAdmin)\n            {\n                if (ModelState.IsValid)\n                {\n                    // Create a unique identifier for the uploaded script\n                    Guid id = Guid.NewGuid();\n\n                    // Create file from uploaded script\n                    string scriptLocation = string.Format(@\"{0}{1}scripts{1}{2}.ace\", _hostingEnv.ContentRootPath, Path.DirectorySeparatorChar, id);\n                    Console.WriteLine(\"ScriptLocation: {0}\", scriptLocation);\n                    System.IO.File.WriteAllBytes(scriptLocation, param.Content);\n\n                    // Add database entry for new script\n                    Script script = new Script\n                    {\n                        Id = id,\n                        Name = param.Name,\n                        Uri = string.Format(@\"/scripts/{0}.ace\", id),\n                        Language = param.Language,\n                        RoutingKey = param.RoutingKey,\n                        CreationTime = DateTime.UtcNow,\n                        LastUpdateTime = DateTime.UtcNow,\n                    };\n                    _context.Scripts.Add(script);\n                    _context.SaveChanges();\n\n                    return Ok(script);\n                }\n                else\n                {\n                    return BadRequest(ModelState);\n                }\n            }\n            else\n            {\n                throw new Exception(\"Only Administrators can upload new scripts.\");\n            }\n        }\n    }\n}"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Controllers/SweepController.cs",
    "content": "﻿using ACEWebService.Entities;\nusing ACEWebService.Services;\nusing ACEWebService.ViewModels;\nusing Microsoft.AspNetCore.Authorization;\nusing Microsoft.AspNetCore.Mvc;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace ACEWebService.Controllers\n{\n    [Authorize(Policy = \"ApiKey\")]\n    [Route(\"ace/[controller]\")]\n    public class SweepController : Controller\n    {\n        private ISweepExecutionService _sweepExecutionService;\n        private ACEWebServiceDbContext _context;\n\n        public SweepController(ISweepExecutionService sweepExecutionService, ACEWebServiceDbContext context)\n        {\n            _sweepExecutionService = sweepExecutionService;\n            _context = context;\n        }\n\n        // GET /ace/sweep\n        [HttpGet()]\n        public IEnumerable<Sweep> Get()\n        {\n            return _context.Sweeps;\n        }\n\n        // GET /ace/sweep/{id}\n        [HttpGet(\"{id}\")]\n        public Sweep Get([FromRoute]Guid Id)\n        {\n            Sweep sweep = _context.Sweeps.Single(s => s.Id == Id);\n            return sweep;\n        }\n\n        // POST /ace/sweep\n        [HttpPost]\n        public IActionResult Post([FromBody]SweepExecutionViewModel param)\n        {\n            if (ModelState.IsValid)\n            {\n                Guid Id = _sweepExecutionService.Sweep(param);\n                return Ok(Id);\n            }\n            else\n            {\n                //return BadRequest(ModelState);\n                return BadRequest(ModelState);\n            }\n        }\n\n        // PUT /ace/sweep/{id}\n        [AllowAnonymous]\n        [HttpPut(\"{id}\")]\n        public IActionResult Put([FromRoute]Guid id, [FromBody]Guid scanId)\n        {\n            if (ModelState.IsValid)\n            {\n                Scan scan = _context.Scans.SingleOrDefault(s => s.Id == scanId);\n                scan.StopTime = DateTime.UtcNow;\n                scan.Status = \"Completed\";\n                _context.Scans.Update(scan);\n                _context.SaveChanges();\n\n                Sweep sweep = _context.Sweeps.SingleOrDefault(sw => sw.Id == id);\n                sweep.CompleteCount++;\n                _context.Sweeps.Update(sweep);\n                _context.SaveChanges();\n\n                return Ok(scanId);\n            }\n            else\n            {\n                return BadRequest(ModelState);\n            }\n        }\n    }\n}"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Controllers/UserController.cs",
    "content": "﻿using ACEWebService.Entities;\nusing ACEWebService.ViewModels;\nusing Microsoft.AspNetCore.Authorization;\nusing Microsoft.AspNetCore.Mvc;\nusing System;\nusing System.Collections.Generic;\nusing System.Linq;\n\nnamespace ACEWebService.Controllers\n{\n    [Authorize(Policy = \"ApiKey\")]\n    [Route(\"ace/[controller]\")]\n    public class UserController : Controller\n    {\n        private ACEWebServiceDbContext _context;\n\n        public UserController(ACEWebServiceDbContext context)\n        {\n            _context = context;\n        }\n\n        // GET /ace/user/delete/{id}\n        [HttpGet(\"delete/{id}\")]\n        public User Delete([FromRoute]Guid id)\n        {\n            User requestor = _context.Users.SingleOrDefault(u => u.ApiKey == Request.Headers[\"X-ApiKey\"]);\n\n            if(requestor.IsAdmin)\n            {\n                if (id == requestor.Id)\n                {\n                    throw new Exception(\"A user cannot delete itself.\");\n                }\n                else\n                {\n                    try\n                    {\n                        User user = _context.Users.SingleOrDefault(u => u.Id == id);\n                        _context.Users.Remove(user);\n                        _context.SaveChanges();\n                        return user;\n                    }\n                    catch\n                    {\n                        throw new Exception(\"Failed to delete account.\");\n                    }\n                }\n            }\n            else\n            {\n                throw new Exception(\"Only Administrator accounts can delete accounts.\");\n            }\n        }\n\n        // GET /ace/user\n        [HttpGet]\n        public IEnumerable<User> Get()\n        {\n            User requestor = _context.Users.SingleOrDefault(u => u.ApiKey == Request.Headers[\"X-ApiKey\"]);\n\n            if(requestor.IsAdmin)\n            {\n                return _context.Users;\n            }\n            else\n            {\n                List<User> userList = new List<User>();\n                userList.Add(requestor);\n                return userList;\n            }\n        }\n\n        // POST /ace/user\n        [HttpPost]\n        public IActionResult Post([FromBody]UserViewModel param)\n        {\n            User requestor = _context.Users.SingleOrDefault(u => u.ApiKey == Request.Headers[\"X-ApiKey\"]);\n\n            if(requestor.IsAdmin)\n            {\n                if (ModelState.IsValid)\n                {\n                    User user = new User\n                    {\n                        UserName = param.UserName,\n                        FirstName = param.FirstName,\n                        LastName = param.LastName,\n                        IsAdmin = param.IsAdmin,\n                        ApiKey = Guid.NewGuid().ToString()\n                    };\n                    _context.Users.Add(user);\n                    _context.SaveChanges();\n                    return Ok(user);\n                }\n                else\n                {\n                    return BadRequest(ModelState);\n                }\n            }\n            else\n            {\n                throw new Exception(\"Only Administrators can create accounts.\");\n            }\n        }\n\n        // PUT /ace/user/{id}\n        [HttpPut(\"{Id}\")]\n        public User Update([FromRoute]Guid Id, [FromBody]UserViewModel param)\n        {\n            User requestor = _context.Users.SingleOrDefault(u => u.ApiKey == Request.Headers[\"X-ApiKey\"]);\n\n            User user = _context.Users.SingleOrDefault(u => u.Id == Id);\n            user.UserName = param.UserName;\n            user.FirstName = param.FirstName;\n            user.LastName = param.LastName;\n            user.IsAdmin = param.IsAdmin;\n            _context.Users.Update(user);\n            _context.SaveChanges();\n            return user;\n        }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/DbModelBuilder.cs",
    "content": "﻿using System;\n\nnamespace ACEWebService.Entities\n{\n    internal class DbModelBuilder\n    {\n        internal object Entity<T>()\n        {\n            throw new NotImplementedException();\n        }\n    }\n}"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Entities/ACEWebServiceDbContext.cs",
    "content": "﻿\nusing Microsoft.EntityFrameworkCore;\n\nnamespace ACEWebService.Entities\n{\n    public class ACEWebServiceDbContext : DbContext\n    {\n        public ACEWebServiceDbContext(DbContextOptions<ACEWebServiceDbContext> options) : base(options)\n        {\n            \n        }\n\n        public DbSet<Computer> Computers { get; set; }\n        public DbSet<Credential> Credentials { get; set; }\n        public DbSet<Download> Downloads { get; set; }\n        public DbSet<Scan> Scans { get; set; }\n        public DbSet<Schedule> Schedules { get; set; }\n        public DbSet<Script> Scripts { get; set; }\n        public DbSet<Sweep> Sweeps { get; set; }\n        public DbSet<User> Users { get; set; }\n    }\n}"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Entities/Computer.cs",
    "content": "﻿using System;\nusing System.ComponentModel.DataAnnotations;\nusing System.ComponentModel.DataAnnotations.Schema;\n\nnamespace ACEWebService.Entities\n{\n    public class Computer\n    {\n        [Key]\n        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]\n        public Guid Id { get; set; }\n        public string ComputerName { get; set; }\n        public string OperatingSystem { get; set; }\n        public bool Scanned { get; set; }\n        public bool SSH { get; set; }\n        public bool RPC { get; set; }\n        public bool SMB { get; set; }\n        public bool WinRM { get; set; }\n        public Guid CredentialId { get; set; }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Entities/ComputerGroup.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel.DataAnnotations;\nusing System.ComponentModel.DataAnnotations.Schema;\n\nnamespace ACEWebService.Entities\n{\n    public class ComputerGroup\n    {\n        [Key]\n        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]\n        public Guid Id { get; set; }\n        public string Name { get; set; }\n        public Guid[] ComputerId { get; set; }\n        public virtual ICollection<Computer> Computer { get; set; }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Entities/Credential.cs",
    "content": "﻿using System;\nusing System.ComponentModel.DataAnnotations;\nusing System.ComponentModel.DataAnnotations.Schema;\n\nnamespace ACEWebService.Entities\n{\n    public class Credential\n    {\n        [Key]\n        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]\n        public Guid Id { get; set; }\n        [Required]\n        public string UserName { get; set; }\n        [Required]\n        public string Password { get; set; }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Entities/Download.cs",
    "content": "﻿using System;\nusing System.ComponentModel.DataAnnotations;\nusing System.ComponentModel.DataAnnotations.Schema;\n\nnamespace ACEWebService.Entities\n{\n    public class Download\n    {\n        [Key]\n        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]\n        public Guid Id { get; set; }\n        [Required]\n        public string ComputerName { get; set; }\n        [Required]\n        public string Name { get; set; }\n        [Required]\n        public string FullPath { get; set; }\n        [Required]\n        public byte[] Content { get; set; }\n        [Required]\n        public DateTime DownloadTime { get; set; }\n    }\n}"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Entities/Scan.cs",
    "content": "﻿using System;\nusing System.ComponentModel.DataAnnotations;\nusing System.ComponentModel.DataAnnotations.Schema;\n\nnamespace ACEWebService.Entities\n{\n    public class Scan\n    {\n        [Key]\n        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]\n        public Guid Id { get; set; }\n        public string Status { get; set; }\n        public DateTime StartTime { get; set; }\n        public DateTime StopTime { get; set; }\n        public Guid ComputerId { get; set; }\n        public virtual Computer Computer { get; set; }\n        public Guid SweepIdentifier { get; set; }\n    }\n}"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Entities/Schedule.cs",
    "content": "﻿using System;\nusing System.ComponentModel.DataAnnotations;\nusing System.ComponentModel.DataAnnotations.Schema;\n\nnamespace ACEWebService.Entities\n{\n    public class Schedule\n    {\n        [Key]\n        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]\n        public Guid Id { get; set; }\n        public string JobName { get; set; }\n        public string TriggerName { get; set; }\n        public DateTime StartTime { get; set; }\n        public int RepeatCount { get; set; }\n        public int ExecutionCount { get; set; }\n        public string ScriptId { get; set; }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Entities/Script.cs",
    "content": "﻿using System;\nusing System.ComponentModel.DataAnnotations;\nusing System.ComponentModel.DataAnnotations.Schema;\n\nnamespace ACEWebService.Entities\n{\n    public class Script\n    {\n        [Key]\n        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]\n        public Guid Id { get; set; }\n        [Required]\n        public string Name { get; set; }\n        [Required]\n        public string Uri { get; set; }\n        [Required]\n        public string Language { get; set; }\n        [Required]\n        public string RoutingKey { get; set; }\n        [Required]\n        public DateTime CreationTime { get; set; }\n        [Required]\n        public DateTime LastUpdateTime { get; set; }\n    }\n}"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Entities/Sweep.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing System.ComponentModel.DataAnnotations;\nusing System.ComponentModel.DataAnnotations.Schema;\n\nnamespace ACEWebService.Entities\n{\n    public class Sweep\n    {\n        [Key]\n        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]\n        public Guid Id { get; set; }\n        public string Status { get; set; }\n        public DateTime StartTime { get; set; }\n        public DateTime EndTime { get; set; }\n        public int ScanCount { get; set; }\n        public int CompleteCount { get; set; }\n        public int ErrorCount { get; set; }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Entities/User.cs",
    "content": "﻿using System;\nusing System.ComponentModel.DataAnnotations;\nusing System.ComponentModel.DataAnnotations.Schema;\n\nnamespace ACEWebService.Entities\n{\n    public class User\n    {\n        [Key]\n        [DatabaseGenerated(DatabaseGeneratedOption.Identity)]\n        public Guid Id { get; set; }\n        [Required]\n        public string UserName { get; set; }\n        public string FirstName { get; set; }\n        public string LastName { get; set; }\n        public bool IsAdmin { get; set; }\n        [Required]\n        public string ApiKey { get; set; }\n    }\n}"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170322221439_MyFirstMigration.Designer.cs",
    "content": "﻿using System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft.EntityFrameworkCore.Metadata;\nusing Microsoft.EntityFrameworkCore.Migrations;\nusing ACEWebService.Entities;\n\nnamespace ACEWebService.Migrations\n{\n    [DbContext(typeof(ACEWebServiceDbContext))]\n    [Migration(\"20170322221439_MyFirstMigration\")]\n    partial class MyFirstMigration\n    {\n        protected override void BuildTargetModel(ModelBuilder modelBuilder)\n        {\n            modelBuilder\n                .HasAnnotation(\"ProductVersion\", \"1.0.1\")\n                .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Computer\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"ComputerName\");\n\n                    b.Property<Guid>(\"CredentialId\");\n\n                    b.Property<string>(\"OperatingSystem\");\n\n                    b.Property<bool>(\"RPC\");\n\n                    b.Property<bool>(\"SMB\");\n\n                    b.Property<bool>(\"SSH\");\n\n                    b.Property<bool>(\"Scanned\");\n\n                    b.Property<bool>(\"WinRM\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"CredentialId\");\n\n                    b.ToTable(\"Computers\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Credential\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"Password\")\n                        .IsRequired();\n\n                    b.Property<string>(\"UserName\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Credentials\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Scan\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<Guid>(\"ComputerId\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.Property<string>(\"Status\");\n\n                    b.Property<DateTime>(\"StopTime\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ComputerId\");\n\n                    b.ToTable(\"Scans\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Schedule\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<int>(\"ExecutionCount\");\n\n                    b.Property<int>(\"Interval\");\n\n                    b.Property<string>(\"Name\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Schedules\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Sweep\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<int>(\"CompleteCount\");\n\n                    b.Property<DateTime>(\"EndTime\");\n\n                    b.Property<int>(\"ScanCount\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.Property<string>(\"Status\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Sweeps\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.User\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"ApiKey\")\n                        .IsRequired();\n\n                    b.Property<string>(\"FirstName\");\n\n                    b.Property<bool>(\"IsAdmin\");\n\n                    b.Property<string>(\"LastName\");\n\n                    b.Property<string>(\"UserName\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Users\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Computer\", b =>\n                {\n                    b.HasOne(\"ACEWebService.Entities.Credential\", \"Credential\")\n                        .WithMany()\n                        .HasForeignKey(\"CredentialId\")\n                        .OnDelete(DeleteBehavior.Cascade);\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Scan\", b =>\n                {\n                    b.HasOne(\"ACEWebService.Entities.Computer\", \"Computer\")\n                        .WithMany()\n                        .HasForeignKey(\"ComputerId\")\n                        .OnDelete(DeleteBehavior.Cascade);\n                });\n        }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170322221439_MyFirstMigration.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace ACEWebService.Migrations\n{\n    public partial class MyFirstMigration : Migration\n    {\n        protected override void Up(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.CreateTable(\n                name: \"Credentials\",\n                columns: table => new\n                {\n                    Id = table.Column<Guid>(nullable: false),\n                    Password = table.Column<string>(nullable: false),\n                    UserName = table.Column<string>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_Credentials\", x => x.Id);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"Schedules\",\n                columns: table => new\n                {\n                    Id = table.Column<Guid>(nullable: false),\n                    ExecutionCount = table.Column<int>(nullable: false),\n                    Interval = table.Column<int>(nullable: false),\n                    Name = table.Column<string>(nullable: true),\n                    StartTime = table.Column<DateTime>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_Schedules\", x => x.Id);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"Sweeps\",\n                columns: table => new\n                {\n                    Id = table.Column<Guid>(nullable: false),\n                    CompleteCount = table.Column<int>(nullable: false),\n                    EndTime = table.Column<DateTime>(nullable: false),\n                    ScanCount = table.Column<int>(nullable: false),\n                    StartTime = table.Column<DateTime>(nullable: false),\n                    Status = table.Column<string>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_Sweeps\", x => x.Id);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"Users\",\n                columns: table => new\n                {\n                    Id = table.Column<Guid>(nullable: false),\n                    ApiKey = table.Column<string>(nullable: false),\n                    FirstName = table.Column<string>(nullable: true),\n                    IsAdmin = table.Column<bool>(nullable: false),\n                    LastName = table.Column<string>(nullable: true),\n                    UserName = table.Column<string>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_Users\", x => x.Id);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"Computers\",\n                columns: table => new\n                {\n                    Id = table.Column<Guid>(nullable: false),\n                    ComputerName = table.Column<string>(nullable: true),\n                    CredentialId = table.Column<Guid>(nullable: false),\n                    OperatingSystem = table.Column<string>(nullable: true),\n                    RPC = table.Column<bool>(nullable: false),\n                    SMB = table.Column<bool>(nullable: false),\n                    SSH = table.Column<bool>(nullable: false),\n                    Scanned = table.Column<bool>(nullable: false),\n                    WinRM = table.Column<bool>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_Computers\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_Computers_Credentials_CredentialId\",\n                        column: x => x.CredentialId,\n                        principalTable: \"Credentials\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateTable(\n                name: \"Scans\",\n                columns: table => new\n                {\n                    Id = table.Column<Guid>(nullable: false),\n                    ComputerId = table.Column<Guid>(nullable: false),\n                    StartTime = table.Column<DateTime>(nullable: false),\n                    Status = table.Column<string>(nullable: true),\n                    StopTime = table.Column<DateTime>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_Scans\", x => x.Id);\n                    table.ForeignKey(\n                        name: \"FK_Scans_Computers_ComputerId\",\n                        column: x => x.ComputerId,\n                        principalTable: \"Computers\",\n                        principalColumn: \"Id\",\n                        onDelete: ReferentialAction.Cascade);\n                });\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_Computers_CredentialId\",\n                table: \"Computers\",\n                column: \"CredentialId\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_Scans_ComputerId\",\n                table: \"Scans\",\n                column: \"ComputerId\");\n        }\n\n        protected override void Down(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.DropTable(\n                name: \"Scans\");\n\n            migrationBuilder.DropTable(\n                name: \"Schedules\");\n\n            migrationBuilder.DropTable(\n                name: \"Sweeps\");\n\n            migrationBuilder.DropTable(\n                name: \"Users\");\n\n            migrationBuilder.DropTable(\n                name: \"Computers\");\n\n            migrationBuilder.DropTable(\n                name: \"Credentials\");\n        }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170322222622_MySecondMigration.Designer.cs",
    "content": "﻿using System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft.EntityFrameworkCore.Metadata;\nusing Microsoft.EntityFrameworkCore.Migrations;\nusing ACEWebService.Entities;\n\nnamespace ACEWebService.Migrations\n{\n    [DbContext(typeof(ACEWebServiceDbContext))]\n    [Migration(\"20170322222622_MySecondMigration\")]\n    partial class MySecondMigration\n    {\n        protected override void BuildTargetModel(ModelBuilder modelBuilder)\n        {\n            modelBuilder\n                .HasAnnotation(\"ProductVersion\", \"1.0.1\")\n                .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Computer\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"ComputerName\");\n\n                    b.Property<Guid>(\"CredentialId\");\n\n                    b.Property<string>(\"OperatingSystem\");\n\n                    b.Property<bool>(\"RPC\");\n\n                    b.Property<bool>(\"SMB\");\n\n                    b.Property<bool>(\"SSH\");\n\n                    b.Property<bool>(\"Scanned\");\n\n                    b.Property<bool>(\"WinRM\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"CredentialId\");\n\n                    b.ToTable(\"Computers\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Credential\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"Password\")\n                        .IsRequired();\n\n                    b.Property<string>(\"UserName\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Credentials\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Scan\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<Guid>(\"ComputerId\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.Property<string>(\"Status\");\n\n                    b.Property<DateTime>(\"StopTime\");\n\n                    b.Property<Guid?>(\"SweepId\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ComputerId\");\n\n                    b.HasIndex(\"SweepId\");\n\n                    b.ToTable(\"Scans\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Schedule\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<int>(\"ExecutionCount\");\n\n                    b.Property<int>(\"Interval\");\n\n                    b.Property<string>(\"Name\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Schedules\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Sweep\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<int>(\"CompleteCount\");\n\n                    b.Property<DateTime>(\"EndTime\");\n\n                    b.Property<int>(\"ScanCount\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.Property<string>(\"Status\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Sweeps\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.User\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"ApiKey\")\n                        .IsRequired();\n\n                    b.Property<string>(\"FirstName\");\n\n                    b.Property<bool>(\"IsAdmin\");\n\n                    b.Property<string>(\"LastName\");\n\n                    b.Property<string>(\"UserName\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Users\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Computer\", b =>\n                {\n                    b.HasOne(\"ACEWebService.Entities.Credential\", \"Credential\")\n                        .WithMany()\n                        .HasForeignKey(\"CredentialId\")\n                        .OnDelete(DeleteBehavior.Cascade);\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Scan\", b =>\n                {\n                    b.HasOne(\"ACEWebService.Entities.Computer\", \"Computer\")\n                        .WithMany()\n                        .HasForeignKey(\"ComputerId\")\n                        .OnDelete(DeleteBehavior.Cascade);\n\n                    b.HasOne(\"ACEWebService.Entities.Sweep\")\n                        .WithMany(\"Scans\")\n                        .HasForeignKey(\"SweepId\");\n                });\n        }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170322222622_MySecondMigration.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace ACEWebService.Migrations\n{\n    public partial class MySecondMigration : Migration\n    {\n        protected override void Up(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.AddColumn<Guid>(\n                name: \"SweepId\",\n                table: \"Scans\",\n                nullable: true);\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_Scans_SweepId\",\n                table: \"Scans\",\n                column: \"SweepId\");\n\n            migrationBuilder.AddForeignKey(\n                name: \"FK_Scans_Sweeps_SweepId\",\n                table: \"Scans\",\n                column: \"SweepId\",\n                principalTable: \"Sweeps\",\n                principalColumn: \"Id\",\n                onDelete: ReferentialAction.Restrict);\n        }\n\n        protected override void Down(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.DropForeignKey(\n                name: \"FK_Scans_Sweeps_SweepId\",\n                table: \"Scans\");\n\n            migrationBuilder.DropIndex(\n                name: \"IX_Scans_SweepId\",\n                table: \"Scans\");\n\n            migrationBuilder.DropColumn(\n                name: \"SweepId\",\n                table: \"Scans\");\n        }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170417201050_MyThirdMigration.Designer.cs",
    "content": "﻿using System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft.EntityFrameworkCore.Metadata;\nusing Microsoft.EntityFrameworkCore.Migrations;\nusing ACEWebService.Entities;\n\nnamespace ACEWebService.Migrations\n{\n    [DbContext(typeof(ACEWebServiceDbContext))]\n    [Migration(\"20170417201050_MyThirdMigration\")]\n    partial class MyThirdMigration\n    {\n        protected override void BuildTargetModel(ModelBuilder modelBuilder)\n        {\n            modelBuilder\n                .HasAnnotation(\"ProductVersion\", \"1.0.1\")\n                .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Computer\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"ComputerName\");\n\n                    b.Property<Guid>(\"CredentialId\");\n\n                    b.Property<string>(\"OperatingSystem\");\n\n                    b.Property<bool>(\"RPC\");\n\n                    b.Property<bool>(\"SMB\");\n\n                    b.Property<bool>(\"SSH\");\n\n                    b.Property<bool>(\"Scanned\");\n\n                    b.Property<bool>(\"WinRM\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"CredentialId\");\n\n                    b.ToTable(\"Computers\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Credential\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"Password\")\n                        .IsRequired();\n\n                    b.Property<string>(\"UserName\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Credentials\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Scan\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<Guid>(\"ComputerId\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.Property<string>(\"Status\");\n\n                    b.Property<DateTime>(\"StopTime\");\n\n                    b.Property<Guid?>(\"SweepId\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ComputerId\");\n\n                    b.HasIndex(\"SweepId\");\n\n                    b.ToTable(\"Scans\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Schedule\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<int>(\"ExecutionCount\");\n\n                    b.Property<int>(\"Interval\");\n\n                    b.Property<string>(\"Name\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Schedules\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Sweep\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<int>(\"CompleteCount\");\n\n                    b.Property<DateTime>(\"EndTime\");\n\n                    b.Property<int>(\"ScanCount\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.Property<string>(\"Status\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Sweeps\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.User\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"ApiKey\")\n                        .IsRequired();\n\n                    b.Property<string>(\"FirstName\");\n\n                    b.Property<bool>(\"IsAdmin\");\n\n                    b.Property<string>(\"LastName\");\n\n                    b.Property<string>(\"UserName\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Users\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Computer\", b =>\n                {\n                    b.HasOne(\"ACEWebService.Entities.Credential\", \"Credential\")\n                        .WithMany()\n                        .HasForeignKey(\"CredentialId\")\n                        .OnDelete(DeleteBehavior.Cascade);\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Scan\", b =>\n                {\n                    b.HasOne(\"ACEWebService.Entities.Computer\", \"Computer\")\n                        .WithMany()\n                        .HasForeignKey(\"ComputerId\")\n                        .OnDelete(DeleteBehavior.Cascade);\n\n                    b.HasOne(\"ACEWebService.Entities.Sweep\")\n                        .WithMany(\"Scans\")\n                        .HasForeignKey(\"SweepId\");\n                });\n        }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170417201050_MyThirdMigration.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace ACEWebService.Migrations\n{\n    public partial class MyThirdMigration : Migration\n    {\n        protected override void Up(MigrationBuilder migrationBuilder)\n        {\n\n        }\n\n        protected override void Down(MigrationBuilder migrationBuilder)\n        {\n\n        }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170420231736_MyFourthMigration.Designer.cs",
    "content": "﻿using System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft.EntityFrameworkCore.Metadata;\nusing Microsoft.EntityFrameworkCore.Migrations;\nusing ACEWebService.Entities;\n\nnamespace ACEWebService.Migrations\n{\n    [DbContext(typeof(ACEWebServiceDbContext))]\n    [Migration(\"20170420231736_MyFourthMigration\")]\n    partial class MyFourthMigration\n    {\n        protected override void BuildTargetModel(ModelBuilder modelBuilder)\n        {\n            modelBuilder\n                .HasAnnotation(\"ProductVersion\", \"1.0.1\")\n                .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Computer\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"ComputerName\");\n\n                    b.Property<Guid>(\"CredentialId\");\n\n                    b.Property<string>(\"OperatingSystem\");\n\n                    b.Property<bool>(\"RPC\");\n\n                    b.Property<bool>(\"SMB\");\n\n                    b.Property<bool>(\"SSH\");\n\n                    b.Property<bool>(\"Scanned\");\n\n                    b.Property<bool>(\"WinRM\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"CredentialId\");\n\n                    b.ToTable(\"Computers\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Credential\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"Password\")\n                        .IsRequired();\n\n                    b.Property<string>(\"UserName\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Credentials\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Scan\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<Guid>(\"ComputerId\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.Property<string>(\"Status\");\n\n                    b.Property<DateTime>(\"StopTime\");\n\n                    b.Property<Guid?>(\"SweepId\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ComputerId\");\n\n                    b.HasIndex(\"SweepId\");\n\n                    b.ToTable(\"Scans\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Schedule\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<int>(\"ExecutionCount\");\n\n                    b.Property<int>(\"Interval\");\n\n                    b.Property<string>(\"Name\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Schedules\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Sweep\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<int>(\"CompleteCount\");\n\n                    b.Property<DateTime>(\"EndTime\");\n\n                    b.Property<int>(\"ErrorCount\");\n\n                    b.Property<int>(\"ScanCount\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.Property<string>(\"Status\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Sweeps\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.User\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"ApiKey\")\n                        .IsRequired();\n\n                    b.Property<string>(\"FirstName\");\n\n                    b.Property<bool>(\"IsAdmin\");\n\n                    b.Property<string>(\"LastName\");\n\n                    b.Property<string>(\"UserName\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Users\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Computer\", b =>\n                {\n                    b.HasOne(\"ACEWebService.Entities.Credential\", \"Credential\")\n                        .WithMany()\n                        .HasForeignKey(\"CredentialId\")\n                        .OnDelete(DeleteBehavior.Cascade);\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Scan\", b =>\n                {\n                    b.HasOne(\"ACEWebService.Entities.Computer\", \"Computer\")\n                        .WithMany()\n                        .HasForeignKey(\"ComputerId\")\n                        .OnDelete(DeleteBehavior.Cascade);\n\n                    b.HasOne(\"ACEWebService.Entities.Sweep\")\n                        .WithMany(\"Scans\")\n                        .HasForeignKey(\"SweepId\");\n                });\n        }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170420231736_MyFourthMigration.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace ACEWebService.Migrations\n{\n    public partial class MyFourthMigration : Migration\n    {\n        protected override void Up(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.AddColumn<int>(\n                name: \"ErrorCount\",\n                table: \"Sweeps\",\n                nullable: false,\n                defaultValue: 0);\n        }\n\n        protected override void Down(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.DropColumn(\n                name: \"ErrorCount\",\n                table: \"Sweeps\");\n        }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170421030619_MyFifthMigration.Designer.cs",
    "content": "﻿using System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft.EntityFrameworkCore.Metadata;\nusing Microsoft.EntityFrameworkCore.Migrations;\nusing ACEWebService.Entities;\n\nnamespace ACEWebService.Migrations\n{\n    [DbContext(typeof(ACEWebServiceDbContext))]\n    [Migration(\"20170421030619_MyFifthMigration\")]\n    partial class MyFifthMigration\n    {\n        protected override void BuildTargetModel(ModelBuilder modelBuilder)\n        {\n            modelBuilder\n                .HasAnnotation(\"ProductVersion\", \"1.0.1\")\n                .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Computer\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"ComputerName\");\n\n                    b.Property<Guid>(\"CredentialId\");\n\n                    b.Property<string>(\"OperatingSystem\");\n\n                    b.Property<bool>(\"RPC\");\n\n                    b.Property<bool>(\"SMB\");\n\n                    b.Property<bool>(\"SSH\");\n\n                    b.Property<bool>(\"Scanned\");\n\n                    b.Property<bool>(\"WinRM\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"CredentialId\");\n\n                    b.ToTable(\"Computers\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Credential\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"Password\")\n                        .IsRequired();\n\n                    b.Property<string>(\"UserName\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Credentials\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Scan\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<Guid>(\"ComputerId\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.Property<string>(\"Status\");\n\n                    b.Property<DateTime>(\"StopTime\");\n\n                    b.Property<Guid?>(\"SweepId\");\n\n                    b.Property<Guid>(\"SweepIdentifier\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ComputerId\");\n\n                    b.HasIndex(\"SweepId\");\n\n                    b.ToTable(\"Scans\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Schedule\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<int>(\"ExecutionCount\");\n\n                    b.Property<int>(\"Interval\");\n\n                    b.Property<string>(\"Name\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Schedules\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Sweep\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<int>(\"CompleteCount\");\n\n                    b.Property<DateTime>(\"EndTime\");\n\n                    b.Property<int>(\"ErrorCount\");\n\n                    b.Property<int>(\"ScanCount\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.Property<string>(\"Status\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Sweeps\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.User\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"ApiKey\")\n                        .IsRequired();\n\n                    b.Property<string>(\"FirstName\");\n\n                    b.Property<bool>(\"IsAdmin\");\n\n                    b.Property<string>(\"LastName\");\n\n                    b.Property<string>(\"UserName\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Users\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Computer\", b =>\n                {\n                    b.HasOne(\"ACEWebService.Entities.Credential\", \"Credential\")\n                        .WithMany()\n                        .HasForeignKey(\"CredentialId\")\n                        .OnDelete(DeleteBehavior.Cascade);\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Scan\", b =>\n                {\n                    b.HasOne(\"ACEWebService.Entities.Computer\", \"Computer\")\n                        .WithMany()\n                        .HasForeignKey(\"ComputerId\")\n                        .OnDelete(DeleteBehavior.Cascade);\n\n                    b.HasOne(\"ACEWebService.Entities.Sweep\")\n                        .WithMany(\"Scans\")\n                        .HasForeignKey(\"SweepId\");\n                });\n        }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170421030619_MyFifthMigration.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace ACEWebService.Migrations\n{\n    public partial class MyFifthMigration : Migration\n    {\n        protected override void Up(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.AddColumn<Guid>(\n                name: \"SweepIdentifier\",\n                table: \"Scans\",\n                nullable: false,\n                defaultValue: new Guid(\"00000000-0000-0000-0000-000000000000\"));\n        }\n\n        protected override void Down(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.DropColumn(\n                name: \"SweepIdentifier\",\n                table: \"Scans\");\n        }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170429215921_MySixthMigration.Designer.cs",
    "content": "﻿using System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft.EntityFrameworkCore.Metadata;\nusing Microsoft.EntityFrameworkCore.Migrations;\nusing ACEWebService.Entities;\n\nnamespace ACEWebService.Migrations\n{\n    [DbContext(typeof(ACEWebServiceDbContext))]\n    [Migration(\"20170429215921_MySixthMigration\")]\n    partial class MySixthMigration\n    {\n        protected override void BuildTargetModel(ModelBuilder modelBuilder)\n        {\n            modelBuilder\n                .HasAnnotation(\"ProductVersion\", \"1.0.1\")\n                .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Computer\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"ComputerName\");\n\n                    b.Property<Guid>(\"CredentialId\");\n\n                    b.Property<string>(\"OperatingSystem\");\n\n                    b.Property<bool>(\"RPC\");\n\n                    b.Property<bool>(\"SMB\");\n\n                    b.Property<bool>(\"SSH\");\n\n                    b.Property<bool>(\"Scanned\");\n\n                    b.Property<bool>(\"WinRM\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"CredentialId\");\n\n                    b.ToTable(\"Computers\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Credential\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"Password\")\n                        .IsRequired();\n\n                    b.Property<string>(\"UserName\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Credentials\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Scan\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<Guid>(\"ComputerId\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.Property<string>(\"Status\");\n\n                    b.Property<DateTime>(\"StopTime\");\n\n                    b.Property<Guid>(\"SweepIdentifier\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ComputerId\");\n\n                    b.ToTable(\"Scans\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Schedule\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<int>(\"ExecutionCount\");\n\n                    b.Property<int>(\"Interval\");\n\n                    b.Property<string>(\"Name\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Schedules\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Script\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<DateTime>(\"CreationTime\");\n\n                    b.Property<string>(\"Language\")\n                        .IsRequired();\n\n                    b.Property<DateTime>(\"LastUpdateTime\");\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired();\n\n                    b.Property<string>(\"Uri\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Scripts\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Sweep\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<int>(\"CompleteCount\");\n\n                    b.Property<DateTime>(\"EndTime\");\n\n                    b.Property<int>(\"ErrorCount\");\n\n                    b.Property<int>(\"ScanCount\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.Property<string>(\"Status\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Sweeps\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.User\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"ApiKey\")\n                        .IsRequired();\n\n                    b.Property<string>(\"FirstName\");\n\n                    b.Property<bool>(\"IsAdmin\");\n\n                    b.Property<string>(\"LastName\");\n\n                    b.Property<string>(\"UserName\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Users\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Computer\", b =>\n                {\n                    b.HasOne(\"ACEWebService.Entities.Credential\", \"Credential\")\n                        .WithMany()\n                        .HasForeignKey(\"CredentialId\")\n                        .OnDelete(DeleteBehavior.Cascade);\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Scan\", b =>\n                {\n                    b.HasOne(\"ACEWebService.Entities.Computer\", \"Computer\")\n                        .WithMany()\n                        .HasForeignKey(\"ComputerId\")\n                        .OnDelete(DeleteBehavior.Cascade);\n                });\n        }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170429215921_MySixthMigration.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace ACEWebService.Migrations\n{\n    public partial class MySixthMigration : Migration\n    {\n        protected override void Up(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.DropForeignKey(\n                name: \"FK_Scans_Sweeps_SweepId\",\n                table: \"Scans\");\n\n            migrationBuilder.DropIndex(\n                name: \"IX_Scans_SweepId\",\n                table: \"Scans\");\n\n            migrationBuilder.DropColumn(\n                name: \"SweepId\",\n                table: \"Scans\");\n\n            migrationBuilder.CreateTable(\n                name: \"Scripts\",\n                columns: table => new\n                {\n                    Id = table.Column<Guid>(nullable: false),\n                    CreationTime = table.Column<DateTime>(nullable: false),\n                    Language = table.Column<string>(nullable: false),\n                    LastUpdateTime = table.Column<DateTime>(nullable: false),\n                    Name = table.Column<string>(nullable: false),\n                    Uri = table.Column<string>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_Scripts\", x => x.Id);\n                });\n\n            migrationBuilder.AlterColumn<string>(\n                name: \"Status\",\n                table: \"Sweeps\",\n                nullable: true);\n        }\n\n        protected override void Down(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.DropTable(\n                name: \"Scripts\");\n\n            migrationBuilder.AddColumn<Guid>(\n                name: \"SweepId\",\n                table: \"Scans\",\n                nullable: true);\n\n            migrationBuilder.AlterColumn<string>(\n                name: \"Status\",\n                table: \"Sweeps\",\n                nullable: false);\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_Scans_SweepId\",\n                table: \"Scans\",\n                column: \"SweepId\");\n\n            migrationBuilder.AddForeignKey(\n                name: \"FK_Scans_Sweeps_SweepId\",\n                table: \"Scans\",\n                column: \"SweepId\",\n                principalTable: \"Sweeps\",\n                principalColumn: \"Id\",\n                onDelete: ReferentialAction.Restrict);\n        }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170430141205_MySeventhMigration.Designer.cs",
    "content": "﻿using System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft.EntityFrameworkCore.Metadata;\nusing Microsoft.EntityFrameworkCore.Migrations;\nusing ACEWebService.Entities;\n\nnamespace ACEWebService.Migrations\n{\n    [DbContext(typeof(ACEWebServiceDbContext))]\n    [Migration(\"20170430141205_MySeventhMigration\")]\n    partial class MySeventhMigration\n    {\n        protected override void BuildTargetModel(ModelBuilder modelBuilder)\n        {\n            modelBuilder\n                .HasAnnotation(\"ProductVersion\", \"1.0.1\")\n                .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Computer\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"ComputerName\");\n\n                    b.Property<Guid>(\"CredentialId\");\n\n                    b.Property<string>(\"OperatingSystem\");\n\n                    b.Property<bool>(\"RPC\");\n\n                    b.Property<bool>(\"SMB\");\n\n                    b.Property<bool>(\"SSH\");\n\n                    b.Property<bool>(\"Scanned\");\n\n                    b.Property<bool>(\"WinRM\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"CredentialId\");\n\n                    b.ToTable(\"Computers\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Credential\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"Password\")\n                        .IsRequired();\n\n                    b.Property<string>(\"UserName\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Credentials\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Download\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<DateTime>(\"AccessedTime\");\n\n                    b.Property<DateTime>(\"BornTime\");\n\n                    b.Property<string>(\"ComputerName\")\n                        .IsRequired();\n\n                    b.Property<DateTime>(\"DownloadTime\");\n\n                    b.Property<string>(\"FullPath\")\n                        .IsRequired();\n\n                    b.Property<DateTime>(\"ModifiedTime\");\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Downloads\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Scan\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<Guid>(\"ComputerId\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.Property<string>(\"Status\");\n\n                    b.Property<DateTime>(\"StopTime\");\n\n                    b.Property<Guid>(\"SweepIdentifier\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ComputerId\");\n\n                    b.ToTable(\"Scans\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Schedule\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<int>(\"ExecutionCount\");\n\n                    b.Property<int>(\"Interval\");\n\n                    b.Property<string>(\"Name\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Schedules\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Script\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<DateTime>(\"CreationTime\");\n\n                    b.Property<string>(\"Language\")\n                        .IsRequired();\n\n                    b.Property<DateTime>(\"LastUpdateTime\");\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired();\n\n                    b.Property<string>(\"Uri\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Scripts\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Sweep\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<int>(\"CompleteCount\");\n\n                    b.Property<DateTime>(\"EndTime\");\n\n                    b.Property<int>(\"ErrorCount\");\n\n                    b.Property<int>(\"ScanCount\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.Property<string>(\"Status\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Sweeps\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.User\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"ApiKey\")\n                        .IsRequired();\n\n                    b.Property<string>(\"FirstName\");\n\n                    b.Property<bool>(\"IsAdmin\");\n\n                    b.Property<string>(\"LastName\");\n\n                    b.Property<string>(\"UserName\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Users\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Computer\", b =>\n                {\n                    b.HasOne(\"ACEWebService.Entities.Credential\", \"Credential\")\n                        .WithMany()\n                        .HasForeignKey(\"CredentialId\")\n                        .OnDelete(DeleteBehavior.Cascade);\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Scan\", b =>\n                {\n                    b.HasOne(\"ACEWebService.Entities.Computer\", \"Computer\")\n                        .WithMany()\n                        .HasForeignKey(\"ComputerId\")\n                        .OnDelete(DeleteBehavior.Cascade);\n                });\n        }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170430141205_MySeventhMigration.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace ACEWebService.Migrations\n{\n    public partial class MySeventhMigration : Migration\n    {\n        protected override void Up(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.CreateTable(\n                name: \"Downloads\",\n                columns: table => new\n                {\n                    Id = table.Column<Guid>(nullable: false),\n                    AccessedTime = table.Column<DateTime>(nullable: false),\n                    BornTime = table.Column<DateTime>(nullable: false),\n                    ComputerName = table.Column<string>(nullable: false),\n                    DownloadTime = table.Column<DateTime>(nullable: false),\n                    FullPath = table.Column<string>(nullable: false),\n                    ModifiedTime = table.Column<DateTime>(nullable: false),\n                    Name = table.Column<string>(nullable: false)\n                },\n                constraints: table =>\n                {\n                    table.PrimaryKey(\"PK_Downloads\", x => x.Id);\n                });\n        }\n\n        protected override void Down(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.DropTable(\n                name: \"Downloads\");\n        }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170707032113_MyEigthMigration.Designer.cs",
    "content": "﻿using System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft.EntityFrameworkCore.Metadata;\nusing Microsoft.EntityFrameworkCore.Migrations;\nusing ACEWebService.Entities;\n\nnamespace ACEWebService.Migrations\n{\n    [DbContext(typeof(ACEWebServiceDbContext))]\n    [Migration(\"20170707032113_MyEigthMigration\")]\n    partial class MyEigthMigration\n    {\n        protected override void BuildTargetModel(ModelBuilder modelBuilder)\n        {\n            modelBuilder\n                .HasAnnotation(\"ProductVersion\", \"1.0.1\")\n                .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Computer\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"ComputerName\");\n\n                    b.Property<Guid>(\"CredentialId\");\n\n                    b.Property<string>(\"OperatingSystem\");\n\n                    b.Property<bool>(\"RPC\");\n\n                    b.Property<bool>(\"SMB\");\n\n                    b.Property<bool>(\"SSH\");\n\n                    b.Property<bool>(\"Scanned\");\n\n                    b.Property<bool>(\"WinRM\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"CredentialId\");\n\n                    b.ToTable(\"Computers\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Credential\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"Password\")\n                        .IsRequired();\n\n                    b.Property<string>(\"UserName\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Credentials\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Download\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<DateTime>(\"AccessedTime\");\n\n                    b.Property<DateTime>(\"BornTime\");\n\n                    b.Property<string>(\"ComputerName\")\n                        .IsRequired();\n\n                    b.Property<DateTime>(\"DownloadTime\");\n\n                    b.Property<string>(\"FullPath\")\n                        .IsRequired();\n\n                    b.Property<DateTime>(\"ModifiedTime\");\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Downloads\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Scan\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<Guid>(\"ComputerId\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.Property<string>(\"Status\");\n\n                    b.Property<DateTime>(\"StopTime\");\n\n                    b.Property<Guid>(\"SweepIdentifier\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ComputerId\");\n\n                    b.ToTable(\"Scans\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Schedule\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<int>(\"ExecutionCount\");\n\n                    b.Property<int>(\"Interval\");\n\n                    b.Property<string>(\"JobName\");\n\n                    b.Property<string>(\"Name\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.Property<string>(\"TriggerName\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Schedules\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Script\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<DateTime>(\"CreationTime\");\n\n                    b.Property<string>(\"Language\")\n                        .IsRequired();\n\n                    b.Property<DateTime>(\"LastUpdateTime\");\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired();\n\n                    b.Property<string>(\"Uri\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Scripts\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Sweep\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<int>(\"CompleteCount\");\n\n                    b.Property<DateTime>(\"EndTime\");\n\n                    b.Property<int>(\"ErrorCount\");\n\n                    b.Property<int>(\"ScanCount\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.Property<string>(\"Status\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Sweeps\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.User\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"ApiKey\")\n                        .IsRequired();\n\n                    b.Property<string>(\"FirstName\");\n\n                    b.Property<bool>(\"IsAdmin\");\n\n                    b.Property<string>(\"LastName\");\n\n                    b.Property<string>(\"UserName\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Users\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Computer\", b =>\n                {\n                    b.HasOne(\"ACEWebService.Entities.Credential\", \"Credential\")\n                        .WithMany()\n                        .HasForeignKey(\"CredentialId\")\n                        .OnDelete(DeleteBehavior.Cascade);\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Scan\", b =>\n                {\n                    b.HasOne(\"ACEWebService.Entities.Computer\", \"Computer\")\n                        .WithMany()\n                        .HasForeignKey(\"ComputerId\")\n                        .OnDelete(DeleteBehavior.Cascade);\n                });\n        }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170707032113_MyEigthMigration.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace ACEWebService.Migrations\n{\n    public partial class MyEigthMigration : Migration\n    {\n        protected override void Up(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.AddColumn<string>(\n                name: \"JobName\",\n                table: \"Schedules\",\n                nullable: true);\n\n            migrationBuilder.AddColumn<string>(\n                name: \"TriggerName\",\n                table: \"Schedules\",\n                nullable: true);\n        }\n\n        protected override void Down(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.DropColumn(\n                name: \"JobName\",\n                table: \"Schedules\");\n\n            migrationBuilder.DropColumn(\n                name: \"TriggerName\",\n                table: \"Schedules\");\n        }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170707040959_MyNinthMigration.Designer.cs",
    "content": "﻿using System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft.EntityFrameworkCore.Metadata;\nusing Microsoft.EntityFrameworkCore.Migrations;\nusing ACEWebService.Entities;\n\nnamespace ACEWebService.Migrations\n{\n    [DbContext(typeof(ACEWebServiceDbContext))]\n    [Migration(\"20170707040959_MyNinthMigration\")]\n    partial class MyNinthMigration\n    {\n        protected override void BuildTargetModel(ModelBuilder modelBuilder)\n        {\n            modelBuilder\n                .HasAnnotation(\"ProductVersion\", \"1.0.1\")\n                .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Computer\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"ComputerName\");\n\n                    b.Property<Guid>(\"CredentialId\");\n\n                    b.Property<string>(\"OperatingSystem\");\n\n                    b.Property<bool>(\"RPC\");\n\n                    b.Property<bool>(\"SMB\");\n\n                    b.Property<bool>(\"SSH\");\n\n                    b.Property<bool>(\"Scanned\");\n\n                    b.Property<bool>(\"WinRM\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"CredentialId\");\n\n                    b.ToTable(\"Computers\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Credential\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"Password\")\n                        .IsRequired();\n\n                    b.Property<string>(\"UserName\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Credentials\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Download\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<DateTime>(\"AccessedTime\");\n\n                    b.Property<DateTime>(\"BornTime\");\n\n                    b.Property<string>(\"ComputerName\")\n                        .IsRequired();\n\n                    b.Property<DateTime>(\"DownloadTime\");\n\n                    b.Property<string>(\"FullPath\")\n                        .IsRequired();\n\n                    b.Property<DateTime>(\"ModifiedTime\");\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Downloads\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Scan\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<Guid>(\"ComputerId\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.Property<string>(\"Status\");\n\n                    b.Property<DateTime>(\"StopTime\");\n\n                    b.Property<Guid>(\"SweepIdentifier\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ComputerId\");\n\n                    b.ToTable(\"Scans\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Schedule\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<int>(\"ExecutionCount\");\n\n                    b.Property<string>(\"JobName\");\n\n                    b.Property<string>(\"ScriptId\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.Property<string>(\"TriggerName\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Schedules\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Script\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<DateTime>(\"CreationTime\");\n\n                    b.Property<string>(\"Language\")\n                        .IsRequired();\n\n                    b.Property<DateTime>(\"LastUpdateTime\");\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired();\n\n                    b.Property<string>(\"Uri\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Scripts\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Sweep\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<int>(\"CompleteCount\");\n\n                    b.Property<DateTime>(\"EndTime\");\n\n                    b.Property<int>(\"ErrorCount\");\n\n                    b.Property<int>(\"ScanCount\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.Property<string>(\"Status\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Sweeps\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.User\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"ApiKey\")\n                        .IsRequired();\n\n                    b.Property<string>(\"FirstName\");\n\n                    b.Property<bool>(\"IsAdmin\");\n\n                    b.Property<string>(\"LastName\");\n\n                    b.Property<string>(\"UserName\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Users\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Computer\", b =>\n                {\n                    b.HasOne(\"ACEWebService.Entities.Credential\", \"Credential\")\n                        .WithMany()\n                        .HasForeignKey(\"CredentialId\")\n                        .OnDelete(DeleteBehavior.Cascade);\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Scan\", b =>\n                {\n                    b.HasOne(\"ACEWebService.Entities.Computer\", \"Computer\")\n                        .WithMany()\n                        .HasForeignKey(\"ComputerId\")\n                        .OnDelete(DeleteBehavior.Cascade);\n                });\n        }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170707040959_MyNinthMigration.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace ACEWebService.Migrations\n{\n    public partial class MyNinthMigration : Migration\n    {\n        protected override void Up(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.DropColumn(\n                name: \"Interval\",\n                table: \"Schedules\");\n\n            migrationBuilder.DropColumn(\n                name: \"Name\",\n                table: \"Schedules\");\n\n            migrationBuilder.AddColumn<string>(\n                name: \"ScriptId\",\n                table: \"Schedules\",\n                nullable: true);\n        }\n\n        protected override void Down(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.DropColumn(\n                name: \"ScriptId\",\n                table: \"Schedules\");\n\n            migrationBuilder.AddColumn<int>(\n                name: \"Interval\",\n                table: \"Schedules\",\n                nullable: false,\n                defaultValue: 0);\n\n            migrationBuilder.AddColumn<string>(\n                name: \"Name\",\n                table: \"Schedules\",\n                nullable: true);\n        }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170707042221_MyTenthMigration.Designer.cs",
    "content": "﻿using System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft.EntityFrameworkCore.Metadata;\nusing Microsoft.EntityFrameworkCore.Migrations;\nusing ACEWebService.Entities;\n\nnamespace ACEWebService.Migrations\n{\n    [DbContext(typeof(ACEWebServiceDbContext))]\n    [Migration(\"20170707042221_MyTenthMigration\")]\n    partial class MyTenthMigration\n    {\n        protected override void BuildTargetModel(ModelBuilder modelBuilder)\n        {\n            modelBuilder\n                .HasAnnotation(\"ProductVersion\", \"1.0.1\")\n                .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Computer\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"ComputerName\");\n\n                    b.Property<Guid>(\"CredentialId\");\n\n                    b.Property<string>(\"OperatingSystem\");\n\n                    b.Property<bool>(\"RPC\");\n\n                    b.Property<bool>(\"SMB\");\n\n                    b.Property<bool>(\"SSH\");\n\n                    b.Property<bool>(\"Scanned\");\n\n                    b.Property<bool>(\"WinRM\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"CredentialId\");\n\n                    b.ToTable(\"Computers\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Credential\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"Password\")\n                        .IsRequired();\n\n                    b.Property<string>(\"UserName\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Credentials\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Download\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<DateTime>(\"AccessedTime\");\n\n                    b.Property<DateTime>(\"BornTime\");\n\n                    b.Property<string>(\"ComputerName\")\n                        .IsRequired();\n\n                    b.Property<DateTime>(\"DownloadTime\");\n\n                    b.Property<string>(\"FullPath\")\n                        .IsRequired();\n\n                    b.Property<DateTime>(\"ModifiedTime\");\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Downloads\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Scan\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<Guid>(\"ComputerId\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.Property<string>(\"Status\");\n\n                    b.Property<DateTime>(\"StopTime\");\n\n                    b.Property<Guid>(\"SweepIdentifier\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ComputerId\");\n\n                    b.ToTable(\"Scans\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Schedule\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<int>(\"ExecutionCount\");\n\n                    b.Property<string>(\"JobName\");\n\n                    b.Property<int>(\"RepeatCount\");\n\n                    b.Property<string>(\"ScriptId\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.Property<string>(\"TriggerName\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Schedules\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Script\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<DateTime>(\"CreationTime\");\n\n                    b.Property<string>(\"Language\")\n                        .IsRequired();\n\n                    b.Property<DateTime>(\"LastUpdateTime\");\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired();\n\n                    b.Property<string>(\"Uri\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Scripts\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Sweep\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<int>(\"CompleteCount\");\n\n                    b.Property<DateTime>(\"EndTime\");\n\n                    b.Property<int>(\"ErrorCount\");\n\n                    b.Property<int>(\"ScanCount\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.Property<string>(\"Status\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Sweeps\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.User\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"ApiKey\")\n                        .IsRequired();\n\n                    b.Property<string>(\"FirstName\");\n\n                    b.Property<bool>(\"IsAdmin\");\n\n                    b.Property<string>(\"LastName\");\n\n                    b.Property<string>(\"UserName\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Users\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Computer\", b =>\n                {\n                    b.HasOne(\"ACEWebService.Entities.Credential\", \"Credential\")\n                        .WithMany()\n                        .HasForeignKey(\"CredentialId\")\n                        .OnDelete(DeleteBehavior.Cascade);\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Scan\", b =>\n                {\n                    b.HasOne(\"ACEWebService.Entities.Computer\", \"Computer\")\n                        .WithMany()\n                        .HasForeignKey(\"ComputerId\")\n                        .OnDelete(DeleteBehavior.Cascade);\n                });\n        }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170707042221_MyTenthMigration.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace ACEWebService.Migrations\n{\n    public partial class MyTenthMigration : Migration\n    {\n        protected override void Up(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.AddColumn<int>(\n                name: \"RepeatCount\",\n                table: \"Schedules\",\n                nullable: false,\n                defaultValue: 0);\n        }\n\n        protected override void Down(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.DropColumn(\n                name: \"RepeatCount\",\n                table: \"Schedules\");\n        }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170713053904_MyEleventhMigration.Designer.cs",
    "content": "﻿using System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft.EntityFrameworkCore.Metadata;\nusing Microsoft.EntityFrameworkCore.Migrations;\nusing ACEWebService.Entities;\n\nnamespace ACEWebService.Migrations\n{\n    [DbContext(typeof(ACEWebServiceDbContext))]\n    [Migration(\"20170713053904_MyEleventhMigration\")]\n    partial class MyEleventhMigration\n    {\n        protected override void BuildTargetModel(ModelBuilder modelBuilder)\n        {\n            modelBuilder\n                .HasAnnotation(\"ProductVersion\", \"1.0.1\")\n                .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Computer\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"ComputerName\");\n\n                    b.Property<Guid>(\"CredentialId\");\n\n                    b.Property<string>(\"OperatingSystem\");\n\n                    b.Property<bool>(\"RPC\");\n\n                    b.Property<bool>(\"SMB\");\n\n                    b.Property<bool>(\"SSH\");\n\n                    b.Property<bool>(\"Scanned\");\n\n                    b.Property<bool>(\"WinRM\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"CredentialId\");\n\n                    b.ToTable(\"Computers\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Credential\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"Password\")\n                        .IsRequired();\n\n                    b.Property<string>(\"UserName\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Credentials\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Download\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<DateTime>(\"AccessedTime\");\n\n                    b.Property<DateTime>(\"BornTime\");\n\n                    b.Property<string>(\"ComputerName\")\n                        .IsRequired();\n\n                    b.Property<DateTime>(\"DownloadTime\");\n\n                    b.Property<string>(\"FullPath\")\n                        .IsRequired();\n\n                    b.Property<DateTime>(\"ModifiedTime\");\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Downloads\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Scan\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<Guid>(\"ComputerId\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.Property<string>(\"Status\");\n\n                    b.Property<DateTime>(\"StopTime\");\n\n                    b.Property<Guid>(\"SweepIdentifier\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ComputerId\");\n\n                    b.ToTable(\"Scans\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Schedule\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<int>(\"ExecutionCount\");\n\n                    b.Property<string>(\"JobName\");\n\n                    b.Property<int>(\"RepeatCount\");\n\n                    b.Property<string>(\"ScriptId\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.Property<string>(\"TriggerName\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Schedules\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Script\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<DateTime>(\"CreationTime\");\n\n                    b.Property<string>(\"Enrichment\")\n                        .IsRequired();\n\n                    b.Property<string>(\"Language\")\n                        .IsRequired();\n\n                    b.Property<DateTime>(\"LastUpdateTime\");\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired();\n\n                    b.Property<string>(\"Output\")\n                        .IsRequired();\n\n                    b.Property<string>(\"Uri\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Scripts\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Sweep\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<int>(\"CompleteCount\");\n\n                    b.Property<DateTime>(\"EndTime\");\n\n                    b.Property<int>(\"ErrorCount\");\n\n                    b.Property<int>(\"ScanCount\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.Property<string>(\"Status\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Sweeps\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.User\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"ApiKey\")\n                        .IsRequired();\n\n                    b.Property<string>(\"FirstName\");\n\n                    b.Property<bool>(\"IsAdmin\");\n\n                    b.Property<string>(\"LastName\");\n\n                    b.Property<string>(\"UserName\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Users\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Computer\", b =>\n                {\n                    b.HasOne(\"ACEWebService.Entities.Credential\", \"Credential\")\n                        .WithMany()\n                        .HasForeignKey(\"CredentialId\")\n                        .OnDelete(DeleteBehavior.Cascade);\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Scan\", b =>\n                {\n                    b.HasOne(\"ACEWebService.Entities.Computer\", \"Computer\")\n                        .WithMany()\n                        .HasForeignKey(\"ComputerId\")\n                        .OnDelete(DeleteBehavior.Cascade);\n                });\n        }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170713053904_MyEleventhMigration.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace ACEWebService.Migrations\n{\n    public partial class MyEleventhMigration : Migration\n    {\n        protected override void Up(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.AddColumn<string>(\n                name: \"Enrichment\",\n                table: \"Scripts\",\n                nullable: false,\n                defaultValue: \"\");\n\n            migrationBuilder.AddColumn<string>(\n                name: \"Output\",\n                table: \"Scripts\",\n                nullable: false,\n                defaultValue: \"\");\n        }\n\n        protected override void Down(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.DropColumn(\n                name: \"Enrichment\",\n                table: \"Scripts\");\n\n            migrationBuilder.DropColumn(\n                name: \"Output\",\n                table: \"Scripts\");\n        }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20171116210534_MyTwelfthMigration.Designer.cs",
    "content": "﻿using System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft.EntityFrameworkCore.Metadata;\nusing Microsoft.EntityFrameworkCore.Migrations;\nusing ACEWebService.Entities;\n\nnamespace ACEWebService.Migrations\n{\n    [DbContext(typeof(ACEWebServiceDbContext))]\n    [Migration(\"20171116210534_MyTwelfthMigration\")]\n    partial class MyTwelfthMigration\n    {\n        protected override void BuildTargetModel(ModelBuilder modelBuilder)\n        {\n            modelBuilder\n                .HasAnnotation(\"ProductVersion\", \"1.0.3\")\n                .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Computer\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"ComputerName\");\n\n                    b.Property<Guid>(\"CredentialId\");\n\n                    b.Property<string>(\"OperatingSystem\");\n\n                    b.Property<bool>(\"RPC\");\n\n                    b.Property<bool>(\"SMB\");\n\n                    b.Property<bool>(\"SSH\");\n\n                    b.Property<bool>(\"Scanned\");\n\n                    b.Property<bool>(\"WinRM\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Computers\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Credential\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"Password\")\n                        .IsRequired();\n\n                    b.Property<string>(\"UserName\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Credentials\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Download\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<DateTime>(\"AccessedTime\");\n\n                    b.Property<DateTime>(\"BornTime\");\n\n                    b.Property<string>(\"ComputerName\")\n                        .IsRequired();\n\n                    b.Property<DateTime>(\"DownloadTime\");\n\n                    b.Property<string>(\"FullPath\")\n                        .IsRequired();\n\n                    b.Property<DateTime>(\"ModifiedTime\");\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Downloads\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Scan\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<Guid>(\"ComputerId\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.Property<string>(\"Status\");\n\n                    b.Property<DateTime>(\"StopTime\");\n\n                    b.Property<Guid>(\"SweepIdentifier\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ComputerId\");\n\n                    b.ToTable(\"Scans\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Schedule\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<int>(\"ExecutionCount\");\n\n                    b.Property<string>(\"JobName\");\n\n                    b.Property<int>(\"RepeatCount\");\n\n                    b.Property<string>(\"ScriptId\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.Property<string>(\"TriggerName\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Schedules\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Script\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<DateTime>(\"CreationTime\");\n\n                    b.Property<string>(\"Language\")\n                        .IsRequired();\n\n                    b.Property<DateTime>(\"LastUpdateTime\");\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired();\n\n                    b.Property<string>(\"Output\")\n                        .IsRequired();\n\n                    b.Property<string>(\"RoutingKey\")\n                        .IsRequired();\n\n                    b.Property<string>(\"Uri\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Scripts\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Sweep\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<int>(\"CompleteCount\");\n\n                    b.Property<DateTime>(\"EndTime\");\n\n                    b.Property<int>(\"ErrorCount\");\n\n                    b.Property<int>(\"ScanCount\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.Property<string>(\"Status\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Sweeps\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.User\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"ApiKey\")\n                        .IsRequired();\n\n                    b.Property<string>(\"FirstName\");\n\n                    b.Property<bool>(\"IsAdmin\");\n\n                    b.Property<string>(\"LastName\");\n\n                    b.Property<string>(\"UserName\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Users\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Scan\", b =>\n                {\n                    b.HasOne(\"ACEWebService.Entities.Computer\", \"Computer\")\n                        .WithMany()\n                        .HasForeignKey(\"ComputerId\")\n                        .OnDelete(DeleteBehavior.Cascade);\n                });\n        }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20171116210534_MyTwelfthMigration.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace ACEWebService.Migrations\n{\n    public partial class MyTwelfthMigration : Migration\n    {\n        protected override void Up(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.DropForeignKey(\n                name: \"FK_Computers_Credentials_CredentialId\",\n                table: \"Computers\");\n\n            migrationBuilder.DropIndex(\n                name: \"IX_Computers_CredentialId\",\n                table: \"Computers\");\n\n            migrationBuilder.DropColumn(\n                name: \"Enrichment\",\n                table: \"Scripts\");\n\n            migrationBuilder.AddColumn<string>(\n                name: \"RoutingKey\",\n                table: \"Scripts\",\n                nullable: false,\n                defaultValue: \"\");\n        }\n\n        protected override void Down(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.DropColumn(\n                name: \"RoutingKey\",\n                table: \"Scripts\");\n\n            migrationBuilder.AddColumn<string>(\n                name: \"Enrichment\",\n                table: \"Scripts\",\n                nullable: false,\n                defaultValue: \"\");\n\n            migrationBuilder.CreateIndex(\n                name: \"IX_Computers_CredentialId\",\n                table: \"Computers\",\n                column: \"CredentialId\");\n\n            migrationBuilder.AddForeignKey(\n                name: \"FK_Computers_Credentials_CredentialId\",\n                table: \"Computers\",\n                column: \"CredentialId\",\n                principalTable: \"Credentials\",\n                principalColumn: \"Id\",\n                onDelete: ReferentialAction.Cascade);\n        }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20171116211023_MyThirteenthMigration.Designer.cs",
    "content": "﻿using System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft.EntityFrameworkCore.Metadata;\nusing Microsoft.EntityFrameworkCore.Migrations;\nusing ACEWebService.Entities;\n\nnamespace ACEWebService.Migrations\n{\n    [DbContext(typeof(ACEWebServiceDbContext))]\n    [Migration(\"20171116211023_MyThirteenthMigration\")]\n    partial class MyThirteenthMigration\n    {\n        protected override void BuildTargetModel(ModelBuilder modelBuilder)\n        {\n            modelBuilder\n                .HasAnnotation(\"ProductVersion\", \"1.0.3\")\n                .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Computer\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"ComputerName\");\n\n                    b.Property<Guid>(\"CredentialId\");\n\n                    b.Property<string>(\"OperatingSystem\");\n\n                    b.Property<bool>(\"RPC\");\n\n                    b.Property<bool>(\"SMB\");\n\n                    b.Property<bool>(\"SSH\");\n\n                    b.Property<bool>(\"Scanned\");\n\n                    b.Property<bool>(\"WinRM\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Computers\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Credential\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"Password\")\n                        .IsRequired();\n\n                    b.Property<string>(\"UserName\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Credentials\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Download\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"ComputerName\")\n                        .IsRequired();\n\n                    b.Property<byte[]>(\"Content\")\n                        .IsRequired();\n\n                    b.Property<string>(\"FullPath\")\n                        .IsRequired();\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Downloads\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Scan\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<Guid>(\"ComputerId\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.Property<string>(\"Status\");\n\n                    b.Property<DateTime>(\"StopTime\");\n\n                    b.Property<Guid>(\"SweepIdentifier\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ComputerId\");\n\n                    b.ToTable(\"Scans\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Schedule\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<int>(\"ExecutionCount\");\n\n                    b.Property<string>(\"JobName\");\n\n                    b.Property<int>(\"RepeatCount\");\n\n                    b.Property<string>(\"ScriptId\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.Property<string>(\"TriggerName\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Schedules\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Script\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<DateTime>(\"CreationTime\");\n\n                    b.Property<string>(\"Language\")\n                        .IsRequired();\n\n                    b.Property<DateTime>(\"LastUpdateTime\");\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired();\n\n                    b.Property<string>(\"RoutingKey\")\n                        .IsRequired();\n\n                    b.Property<string>(\"Uri\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Scripts\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Sweep\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<int>(\"CompleteCount\");\n\n                    b.Property<DateTime>(\"EndTime\");\n\n                    b.Property<int>(\"ErrorCount\");\n\n                    b.Property<int>(\"ScanCount\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.Property<string>(\"Status\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Sweeps\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.User\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"ApiKey\")\n                        .IsRequired();\n\n                    b.Property<string>(\"FirstName\");\n\n                    b.Property<bool>(\"IsAdmin\");\n\n                    b.Property<string>(\"LastName\");\n\n                    b.Property<string>(\"UserName\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Users\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Scan\", b =>\n                {\n                    b.HasOne(\"ACEWebService.Entities.Computer\", \"Computer\")\n                        .WithMany()\n                        .HasForeignKey(\"ComputerId\")\n                        .OnDelete(DeleteBehavior.Cascade);\n                });\n        }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20171116211023_MyThirteenthMigration.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace ACEWebService.Migrations\n{\n    public partial class MyThirteenthMigration : Migration\n    {\n        protected override void Up(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.DropColumn(\n                name: \"Output\",\n                table: \"Scripts\");\n\n            migrationBuilder.DropColumn(\n                name: \"AccessedTime\",\n                table: \"Downloads\");\n\n            migrationBuilder.DropColumn(\n                name: \"BornTime\",\n                table: \"Downloads\");\n\n            migrationBuilder.DropColumn(\n                name: \"DownloadTime\",\n                table: \"Downloads\");\n\n            migrationBuilder.DropColumn(\n                name: \"ModifiedTime\",\n                table: \"Downloads\");\n\n            migrationBuilder.AddColumn<byte[]>(\n                name: \"Content\",\n                table: \"Downloads\",\n                nullable: false,\n                defaultValue: new byte[] {  });\n        }\n\n        protected override void Down(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.DropColumn(\n                name: \"Content\",\n                table: \"Downloads\");\n\n            migrationBuilder.AddColumn<string>(\n                name: \"Output\",\n                table: \"Scripts\",\n                nullable: false,\n                defaultValue: \"\");\n\n            migrationBuilder.AddColumn<DateTime>(\n                name: \"AccessedTime\",\n                table: \"Downloads\",\n                nullable: false,\n                defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));\n\n            migrationBuilder.AddColumn<DateTime>(\n                name: \"BornTime\",\n                table: \"Downloads\",\n                nullable: false,\n                defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));\n\n            migrationBuilder.AddColumn<DateTime>(\n                name: \"DownloadTime\",\n                table: \"Downloads\",\n                nullable: false,\n                defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));\n\n            migrationBuilder.AddColumn<DateTime>(\n                name: \"ModifiedTime\",\n                table: \"Downloads\",\n                nullable: false,\n                defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));\n        }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20171116233431_MyFourteenthMigration.Designer.cs",
    "content": "﻿using System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft.EntityFrameworkCore.Metadata;\nusing Microsoft.EntityFrameworkCore.Migrations;\nusing ACEWebService.Entities;\n\nnamespace ACEWebService.Migrations\n{\n    [DbContext(typeof(ACEWebServiceDbContext))]\n    [Migration(\"20171116233431_MyFourteenthMigration\")]\n    partial class MyFourteenthMigration\n    {\n        protected override void BuildTargetModel(ModelBuilder modelBuilder)\n        {\n            modelBuilder\n                .HasAnnotation(\"ProductVersion\", \"1.0.3\")\n                .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Computer\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"ComputerName\");\n\n                    b.Property<Guid>(\"CredentialId\");\n\n                    b.Property<string>(\"OperatingSystem\");\n\n                    b.Property<bool>(\"RPC\");\n\n                    b.Property<bool>(\"SMB\");\n\n                    b.Property<bool>(\"SSH\");\n\n                    b.Property<bool>(\"Scanned\");\n\n                    b.Property<bool>(\"WinRM\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Computers\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Credential\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"Password\")\n                        .IsRequired();\n\n                    b.Property<string>(\"UserName\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Credentials\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Download\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"ComputerName\")\n                        .IsRequired();\n\n                    b.Property<byte[]>(\"Content\")\n                        .IsRequired();\n\n                    b.Property<DateTime>(\"DownloadTime\");\n\n                    b.Property<string>(\"FullPath\")\n                        .IsRequired();\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Downloads\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Scan\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<Guid>(\"ComputerId\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.Property<string>(\"Status\");\n\n                    b.Property<DateTime>(\"StopTime\");\n\n                    b.Property<Guid>(\"SweepIdentifier\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ComputerId\");\n\n                    b.ToTable(\"Scans\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Schedule\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<int>(\"ExecutionCount\");\n\n                    b.Property<string>(\"JobName\");\n\n                    b.Property<int>(\"RepeatCount\");\n\n                    b.Property<string>(\"ScriptId\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.Property<string>(\"TriggerName\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Schedules\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Script\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<DateTime>(\"CreationTime\");\n\n                    b.Property<string>(\"Language\")\n                        .IsRequired();\n\n                    b.Property<DateTime>(\"LastUpdateTime\");\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired();\n\n                    b.Property<string>(\"RoutingKey\")\n                        .IsRequired();\n\n                    b.Property<string>(\"Uri\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Scripts\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Sweep\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<int>(\"CompleteCount\");\n\n                    b.Property<DateTime>(\"EndTime\");\n\n                    b.Property<int>(\"ErrorCount\");\n\n                    b.Property<int>(\"ScanCount\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.Property<string>(\"Status\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Sweeps\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.User\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"ApiKey\")\n                        .IsRequired();\n\n                    b.Property<string>(\"FirstName\");\n\n                    b.Property<bool>(\"IsAdmin\");\n\n                    b.Property<string>(\"LastName\");\n\n                    b.Property<string>(\"UserName\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Users\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Scan\", b =>\n                {\n                    b.HasOne(\"ACEWebService.Entities.Computer\", \"Computer\")\n                        .WithMany()\n                        .HasForeignKey(\"ComputerId\")\n                        .OnDelete(DeleteBehavior.Cascade);\n                });\n        }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20171116233431_MyFourteenthMigration.cs",
    "content": "﻿using System;\nusing System.Collections.Generic;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace ACEWebService.Migrations\n{\n    public partial class MyFourteenthMigration : Migration\n    {\n        protected override void Up(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.AddColumn<DateTime>(\n                name: \"DownloadTime\",\n                table: \"Downloads\",\n                nullable: false,\n                defaultValue: new DateTime(1, 1, 1, 0, 0, 0, 0, DateTimeKind.Unspecified));\n        }\n\n        protected override void Down(MigrationBuilder migrationBuilder)\n        {\n            migrationBuilder.DropColumn(\n                name: \"DownloadTime\",\n                table: \"Downloads\");\n        }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/ACEWebServiceDbContextModelSnapshot.cs",
    "content": "﻿using System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft.EntityFrameworkCore.Metadata;\nusing Microsoft.EntityFrameworkCore.Migrations;\nusing ACEWebService.Entities;\n\nnamespace ACEWebService.Migrations\n{\n    [DbContext(typeof(ACEWebServiceDbContext))]\n    partial class ACEWebServiceDbContextModelSnapshot : ModelSnapshot\n    {\n        protected override void BuildModel(ModelBuilder modelBuilder)\n        {\n            modelBuilder\n                .HasAnnotation(\"ProductVersion\", \"1.0.3\")\n                .HasAnnotation(\"SqlServer:ValueGenerationStrategy\", SqlServerValueGenerationStrategy.IdentityColumn);\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Computer\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"ComputerName\");\n\n                    b.Property<Guid>(\"CredentialId\");\n\n                    b.Property<string>(\"OperatingSystem\");\n\n                    b.Property<bool>(\"RPC\");\n\n                    b.Property<bool>(\"SMB\");\n\n                    b.Property<bool>(\"SSH\");\n\n                    b.Property<bool>(\"Scanned\");\n\n                    b.Property<bool>(\"WinRM\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Computers\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Credential\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"Password\")\n                        .IsRequired();\n\n                    b.Property<string>(\"UserName\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Credentials\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Download\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"ComputerName\")\n                        .IsRequired();\n\n                    b.Property<byte[]>(\"Content\")\n                        .IsRequired();\n\n                    b.Property<DateTime>(\"DownloadTime\");\n\n                    b.Property<string>(\"FullPath\")\n                        .IsRequired();\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Downloads\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Scan\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<Guid>(\"ComputerId\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.Property<string>(\"Status\");\n\n                    b.Property<DateTime>(\"StopTime\");\n\n                    b.Property<Guid>(\"SweepIdentifier\");\n\n                    b.HasKey(\"Id\");\n\n                    b.HasIndex(\"ComputerId\");\n\n                    b.ToTable(\"Scans\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Schedule\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<int>(\"ExecutionCount\");\n\n                    b.Property<string>(\"JobName\");\n\n                    b.Property<int>(\"RepeatCount\");\n\n                    b.Property<string>(\"ScriptId\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.Property<string>(\"TriggerName\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Schedules\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Script\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<DateTime>(\"CreationTime\");\n\n                    b.Property<string>(\"Language\")\n                        .IsRequired();\n\n                    b.Property<DateTime>(\"LastUpdateTime\");\n\n                    b.Property<string>(\"Name\")\n                        .IsRequired();\n\n                    b.Property<string>(\"RoutingKey\")\n                        .IsRequired();\n\n                    b.Property<string>(\"Uri\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Scripts\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Sweep\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<int>(\"CompleteCount\");\n\n                    b.Property<DateTime>(\"EndTime\");\n\n                    b.Property<int>(\"ErrorCount\");\n\n                    b.Property<int>(\"ScanCount\");\n\n                    b.Property<DateTime>(\"StartTime\");\n\n                    b.Property<string>(\"Status\");\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Sweeps\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.User\", b =>\n                {\n                    b.Property<Guid>(\"Id\")\n                        .ValueGeneratedOnAdd();\n\n                    b.Property<string>(\"ApiKey\")\n                        .IsRequired();\n\n                    b.Property<string>(\"FirstName\");\n\n                    b.Property<bool>(\"IsAdmin\");\n\n                    b.Property<string>(\"LastName\");\n\n                    b.Property<string>(\"UserName\")\n                        .IsRequired();\n\n                    b.HasKey(\"Id\");\n\n                    b.ToTable(\"Users\");\n                });\n\n            modelBuilder.Entity(\"ACEWebService.Entities.Scan\", b =>\n                {\n                    b.HasOne(\"ACEWebService.Entities.Computer\", \"Computer\")\n                        .WithMany()\n                        .HasForeignKey(\"ComputerId\")\n                        .OnDelete(DeleteBehavior.Cascade);\n                });\n        }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Program.cs",
    "content": "﻿using System.IO;\nusing Microsoft.AspNetCore.Hosting;\nusing Microsoft.AspNetCore.Builder;\n\nnamespace ACEWebService\n{\n    public class Program\n    {\n        public static void Main(string[] args)\n        {\n            var host = new WebHostBuilder()\n                .UseKestrel()\n                .UseContentRoot(Directory.GetCurrentDirectory())\n                .UseIISIntegration()\n                .UseStartup<Startup>()\n                .Build();\n\n            host.Run();\n        }\n    }\n}"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Project_Readme.html",
    "content": "﻿<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\" />\n    <title>Welcome to ASP.NET Core</title>\n    <style>\n        html {\n            background: #f1f1f1;\n            height: 100%;\n        }\n\n        body {\n            background: #fff;\n            color: #505050;\n            font: 14px 'Segoe UI', tahoma, arial, helvetica, sans-serif;\n            margin: 1%;\n            min-height: 95.5%;\n            border: 1px solid silver;\n            position: relative;\n        }\n\n        #header {\n            padding: 0;\n        }\n\n            #header h1 {\n                font-size: 44px;\n                font-weight: normal;\n                margin: 0;\n                padding: 10px 30px 10px 30px;\n            }\n\n            #header span {\n                margin: 0;\n                padding: 0 30px;\n                display: block;\n            }\n\n            #header p {\n                font-size: 20px;\n                color: #fff;\n                background: #007acc;\n                padding: 0 30px;\n                line-height: 50px;\n                margin-top: 25px;\n\n            }\n\n                #header p a {\n                    color: #fff;\n                    text-decoration: underline;\n                    font-weight: bold;\n                    padding-right: 35px;\n                    background: no-repeat right bottom url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAAAWCAMAAAAcqPc3AAAANlBMVEUAAAAAeswfitI9mthXp91us+KCvuaTx+mjz+2x1u+83PLH4vTR5/ba7Pjj8Pns9fv1+v3////wy3dWAAAAAXRSTlMAQObYZgAAAHxJREFUeNp9kVcSwCAIRMHUYoH7XzaxOxJ9P8oyQ1uIqNPwh3s2aLmIM2YtqrLcQIeQEylhuCeUOlhgve5yoBCfWmlnlgkN4H8ykbpaE7gR03AbUHiwoOxUH9Xp+ubd41p1HF3mBPrfC87BHeTdaB3ceeKL9HGpcvX9zu6+DdMWT9KQPvYAAAAASUVORK5CYII=);\n                }\n\n        #main {\n            padding: 5px 30px;\n            clear: both;\n        }\n\n        .section {\n            width: 21.7%;\n            float: left;\n            margin: 0 0 0 4%;\n        }\n\n            .section h2 {\n                font-size: 13px;\n                text-transform: uppercase;\n                margin: 0;\n                border-bottom: 1px solid silver;\n                padding-bottom: 12px;\n                margin-bottom: 8px;\n            }\n\n            .section.first {\n                margin-left: 0;\n            }\n\n                .section.first h2 {\n                    font-size: 24px;\n                    text-transform: none;\n                    margin-bottom: 25px;\n                    border: none;\n                }\n\n                .section.first li {\n                    border-top: 1px solid silver;\n                    padding: 8px 0;\n                }\n\n            .section.last {\n                margin-right: 0;\n            }\n\n        ul {\n            list-style: none;\n            padding: 0;\n            margin: 0;\n            line-height: 20px;\n        }\n\n        li {\n            padding: 4px 0;\n        }\n\n        a {\n            color: #267cb2;\n            text-decoration: none;\n        }\n\n            a:hover {\n                text-decoration: underline;\n            }\n\n        #footer {\n            clear: both;\n            padding-top: 50px;\n        }\n\n            #footer p {\n                position: absolute;\n                bottom: 10px;\n            }\n    </style>\n</head>\n<body>\n\n    <div id=\"header\">\n        <h1>Welcome to ASP.NET Core</h1>\n        <span>\n            We've made some big updates in this release, so it’s <b>important</b> that you spend\n            a few minutes to learn what’s new.\n        </span>\n        <p>You've created a new ASP.NET Core project. <a href=\"http://go.microsoft.com/fwlink/?LinkId=518016\">Learn what's new</a></p>\n    </div>\n\n    <div id=\"main\">\n        <div class=\"section first\">\n            <h2>This application consists of:</h2>\n            <ul>\n                <li>Sample pages using ASP.NET Core MVC</li>\n                <li><a href=\"http://go.microsoft.com/fwlink/?LinkId=518004\">Bower</a> for managing client-side libraries</li>\n                <li>Theming using <a href=\"http://go.microsoft.com/fwlink/?LinkID=398939\">Bootstrap</a></li>\n            </ul>\n        </div>\n        <div class=\"section\">\n            <h2>How to</h2>\n            <ul>\n                <li><a href=\"http://go.microsoft.com/fwlink/?LinkID=398600\">Add a Controller and View</a></li>\n                <li><a href=\"http://go.microsoft.com/fwlink/?LinkID=699562\">Add an appsetting in config and access it in app.</a></li>\n                <li><a href=\"http://go.microsoft.com/fwlink/?LinkId=699315\">Manage User Secrets using Secret Manager.</a></li>\n                <li><a href=\"http://go.microsoft.com/fwlink/?LinkId=699316\">Use logging to log a message.</a></li>\n                <li><a href=\"http://go.microsoft.com/fwlink/?LinkId=699317\">Add packages using NuGet.</a></li>\n                <li><a href=\"http://go.microsoft.com/fwlink/?LinkId=699318\">Add client packages using Bower.</a></li>\n                <li><a href=\"http://go.microsoft.com/fwlink/?LinkId=699319\">Target development, staging or production environment.</a></li>\n            </ul>\n        </div>\n        <div class=\"section\">\n            <h2>Overview</h2>\n            <ul>\n                <li><a href=\"http://go.microsoft.com/fwlink/?LinkId=518008\">Conceptual overview of what is ASP.NET Core</a></li>\n                <li><a href=\"http://go.microsoft.com/fwlink/?LinkId=699320\">Fundamentals of ASP.NET Core such as Startup and middleware.</a></li>\n                <li><a href=\"http://go.microsoft.com/fwlink/?LinkId=398602\">Working with Data</a></li>\n                <li><a href=\"http://go.microsoft.com/fwlink/?LinkId=398603\">Security</a></li>\n                <li><a href=\"http://go.microsoft.com/fwlink/?LinkID=699321\">Client side development</a></li>\n                <li><a href=\"http://go.microsoft.com/fwlink/?LinkID=699322\">Develop on different platforms</a></li>\n                <li><a href=\"http://go.microsoft.com/fwlink/?LinkID=699323\">Read more on the documentation site</a></li>\n            </ul>\n        </div>\n        <div class=\"section last\">\n            <h2>Run & Deploy</h2>\n            <ul>\n                <li><a href=\"http://go.microsoft.com/fwlink/?LinkID=517851\">Run your app</a></li>\n                <li><a href=\"http://go.microsoft.com/fwlink/?LinkID=517853\">Run tools such as EF migrations and more</a></li>\n                <li><a href=\"http://go.microsoft.com/fwlink/?LinkID=398609\">Publish to Microsoft Azure Web Apps</a></li>\n            </ul>\n        </div>\n\n        <div id=\"footer\">\n            <p>We would love to hear your <a href=\"http://go.microsoft.com/fwlink/?LinkId=518015\">feedback</a></p>\n        </div>\n    </div>\n\n</body>\n</html>\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Properties/PublishProfiles/ACEWebService-publish.ps1",
    "content": "﻿[cmdletbinding(SupportsShouldProcess=$true)]\nparam($publishProperties=@{}, $packOutput, $pubProfilePath)\n\n# to learn more about this file visit https://go.microsoft.com/fwlink/?LinkId=524327\n\ntry{\n    if ($publishProperties['ProjectGuid'] -eq $null){\n        $publishProperties['ProjectGuid'] = '2794f6a8-a327-40bd-a11f-f72ecdbd2273'\n    }\n\n    $publishModulePath = Join-Path (Split-Path $MyInvocation.MyCommand.Path) 'publish-module.psm1'\n    Import-Module $publishModulePath -DisableNameChecking -Force\n\n    # call Publish-AspNet to perform the publish operation\n    Publish-AspNet -publishProperties $publishProperties -packOutput $packOutput -pubProfilePath $pubProfilePath\n}\ncatch{\n    \"An error occurred during publish.`n{0}\" -f $_.Exception.Message | Write-Error\n}"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Properties/PublishProfiles/ACEWebService.pubxml",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\nThis file is used by the publish/package process of your Web project. You can customize the behavior of this process\nby editing this MSBuild file. In order to learn more about this please visit http://go.microsoft.com/fwlink/?LinkID=208121. \n-->\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <PropertyGroup>\n    <WebPublishMethod>MSDeploy</WebPublishMethod>\n    <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>\n    <LastUsedPlatform>Any CPU</LastUsedPlatform>\n    <SiteUrlToLaunchAfterPublish />\n    <LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>\n    <ExcludeApp_Data>False</ExcludeApp_Data>\n    <PublishFramework />\n    <UsePowerShell>True</UsePowerShell>\n    <EnableMSDeployAppOffline>True</EnableMSDeployAppOffline>\n    <MSDeployServiceURL>http://192.168.92.130</MSDeployServiceURL>\n    <DeployIisAppPath>DIGSWebService</DeployIisAppPath>\n    <RemoteSitePhysicalPath />\n    <SkipExtraFilesOnServer>True</SkipExtraFilesOnServer>\n    <MSDeployPublishMethod>RemoteAgent</MSDeployPublishMethod>\n    <EnableMSDeployBackup>False</EnableMSDeployBackup>\n    <UserName>Administrator</UserName>\n    <_SavePWD>False</_SavePWD>\n  </PropertyGroup>\n</Project>"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Properties/PublishProfiles/FileSystem-publish.ps1",
    "content": "﻿[cmdletbinding(SupportsShouldProcess=$true)]\nparam($publishProperties=@{}, $packOutput, $pubProfilePath)\n\n# to learn more about this file visit https://go.microsoft.com/fwlink/?LinkId=524327\n\ntry{\n    if ($publishProperties['ProjectGuid'] -eq $null){\n        $publishProperties['ProjectGuid'] = '2794f6a8-a327-40bd-a11f-f72ecdbd2273'\n    }\n\n    $publishModulePath = Join-Path (Split-Path $MyInvocation.MyCommand.Path) 'publish-module.psm1'\n    Import-Module $publishModulePath -DisableNameChecking -Force\n\n    # call Publish-AspNet to perform the publish operation\n    Publish-AspNet -publishProperties $publishProperties -packOutput $packOutput -pubProfilePath $pubProfilePath\n}\ncatch{\n    \"An error occurred during publish.`n{0}\" -f $_.Exception.Message | Write-Error\n}"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Properties/PublishProfiles/FileSystem.pubxml",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\nThis file is used by the publish/package process of your Web project. You can customize the behavior of this process\nby editing this MSBuild file. In order to learn more about this please visit http://go.microsoft.com/fwlink/?LinkID=208121. \n-->\n<Project ToolsVersion=\"4.0\" xmlns=\"http://schemas.microsoft.com/developer/msbuild/2003\">\n  <PropertyGroup>\n    <WebPublishMethod>FileSystem</WebPublishMethod>\n    <LastUsedBuildConfiguration>Release</LastUsedBuildConfiguration>\n    <LastUsedPlatform>Any CPU</LastUsedPlatform>\n    <SiteUrlToLaunchAfterPublish />\n    <LaunchSiteAfterPublish>True</LaunchSiteAfterPublish>\n    <ExcludeApp_Data>False</ExcludeApp_Data>\n    <PublishFramework />\n    <UsePowerShell>True</UsePowerShell>\n    <publishUrl>.\\bin\\Release\\PublishOutput</publishUrl>\n    <DeleteExistingFiles>False</DeleteExistingFiles>\n  </PropertyGroup>\n</Project>"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Properties/PublishProfiles/publish-module.psm1",
    "content": "﻿# WARNING:  DO NOT MODIFY this file. Visual Studio will override it.\nparam()\n\n$script:AspNetPublishHandlers = @{}\n\n<#\nThese settings can be overridden with environment variables.\nThe name of the environment variable should use \"Publish\" as a\nprefix and the names below. For example:\n\n    $env:PublishMSDeployUseChecksum = $true\n#>\n$global:AspNetPublishSettings = New-Object -TypeName PSCustomObject @{\n    MsdeployDefaultProperties = @{\n        'MSDeployUseChecksum'=$false\n        'SkipExtraFilesOnServer'=$true\n        'retryAttempts' = 20\n        'EnableMSDeployBackup' = $false\n        'DeleteExistingFiles' = $false\n        'AllowUntrustedCertificate'= $false\n        'MSDeployPackageContentFoldername'='website\\'\n        'EnvironmentName' = 'Production'\n        'AuthType'='Basic'\n        'MSDeployPublishMethod'='WMSVC'\n    }\n}\n\nfunction InternalOverrideSettingsFromEnv{\n    [cmdletbinding()]\n    param(\n        [Parameter(Position=0)]\n        [object[]]$settings = ($global:AspNetPublishSettings,$global:AspNetPublishSettings.MsdeployDefaultProperties),\n\n        [Parameter(Position=1)]\n        [string]$prefix = 'Publish'\n    )\n    process{\n        foreach($settingsObj in $settings){\n            if($settingsObj -eq $null){\n                continue\n            }\n\n            $settingNames = $null\n            if($settingsObj -is [hashtable]){\n                $settingNames = $settingsObj.Keys\n            }\n            else{\n                $settingNames = ($settingsObj | Get-Member -MemberType NoteProperty | Select-Object -ExpandProperty Name)\n\n            }\n\n            foreach($name in @($settingNames)){\n                $fullname = ('{0}{1}' -f $prefix,$name)\n                if(Test-Path \"env:$fullname\"){\n                    $settingsObj.$name = ((get-childitem \"env:$fullname\").Value)\n                }\n            }\n        }\n    }\n}\n\nInternalOverrideSettingsFromEnv -prefix 'Publish' -settings $global:AspNetPublishSettings,$global:AspNetPublishSettings.MsdeployDefaultProperties\n\nfunction Register-AspnetPublishHandler{\n    [cmdletbinding()]\n    param(\n        [Parameter(Mandatory=$true,Position=0)]\n        $name,\n        [Parameter(Mandatory=$true,Position=1)]\n        [ScriptBlock]$handler,\n        [switch]$force\n    )\n    process{        \n        if(!($script:AspNetPublishHandlers[$name]) -or $force ){\n            'Adding handler for [{0}]' -f $name | Write-Verbose\n            $script:AspNetPublishHandlers[$name] = $handler\n        }\n        elseif(!($force)){\n            'Ignoring call to Register-AspnetPublishHandler for [name={0}], because a handler with that name exists and -force was not passed.' -f $name | Write-Verbose\n        }\n    }\n}\n\nfunction Get-AspnetPublishHandler{\n    [cmdletbinding()]\n    param(\n        [Parameter(Mandatory=$true,Position=0)]\n        $name\n    )\n    process{\n        $foundHandler = $script:AspNetPublishHandlers[$name]\n\n        if(!$foundHandler){\n            throw ('AspnetPublishHandler with name \"{0}\" was not found' -f $name)\n        }\n\n        $foundHandler\n    }\n}\n\nfunction GetInternal-ExcludeFilesArg{\n    [cmdletbinding()]\n    param(\n        $publishProperties\n    )\n    process{\n        $excludeFiles = $publishProperties['ExcludeFiles']\n        foreach($exclude in $excludeFiles){\n            if($exclude){\n                [string]$objName = $exclude['objectname']\n\n                if([string]::IsNullOrEmpty($objName)){\n                    $objName = 'filePath'\n                }\n\n                $excludePath = $exclude['absolutepath']\n\n                # output the result to the return list\n                ('-skip:objectName={0},absolutePath=''{1}''' -f $objName, $excludePath)\n            }   \n        }\n    }\n}\n\nfunction GetInternal-ReplacementsMSDeployArgs{\n    [cmdletbinding()]\n    param(\n        $publishProperties\n    )\n    process{\n        foreach($replace in ($publishProperties['Replacements'])){     \n            if($replace){           \n                $typeValue = $replace['type']\n                if(!$typeValue){ $typeValue = 'TextFile' }\n                \n                $file = $replace['file']\n                $match = $replace['match']\n                $newValue = $replace['newValue']\n\n                if($file -and $match -and $newValue){\n                    $setParam = ('-setParam:type={0},scope={1},match={2},value={3}' -f $typeValue,$file, $match,$newValue)\n                    'Adding setparam [{0}]' -f $setParam | Write-Verbose\n\n                    # return it\n                    $setParam\n                }\n                else{\n                    'Skipping replacement because its missing a required value.[file=\"{0}\",match=\"{1}\",newValue=\"{2}\"]' -f $file,$match,$newValue | Write-Verbose\n                }\n            }\n        }       \n    }\n}\n\n<#\n.SYNOPSIS\nReturns an array of msdeploy arguments that are used across different providers.\nFor example this will handle useChecksum, AppOffline etc.\nThis will also add default properties if they are missing.\n#>\nfunction GetInternal-SharedMSDeployParametersFrom{\n    [cmdletbinding()]\n    param(\n        [Parameter(Mandatory=$true,Position=0)]\n        [HashTable]$publishProperties,\n        [Parameter(Mandatory=$true,Position=1)]\n        [System.IO.FileInfo]$packOutput\n    )\n    process{\n        $sharedArgs = New-Object psobject -Property @{\n            ExtraArgs = @()\n            DestFragment = ''\n            EFMigrationData = @{}\n        }\n\n        # add default properties if they are missing\n        foreach($propName in $global:AspNetPublishSettings.MsdeployDefaultProperties.Keys){\n            if($publishProperties[\"$propName\"] -eq $null){\n                $defValue = $global:AspNetPublishSettings.MsdeployDefaultProperties[\"$propName\"]\n                'Adding default property to publishProperties [\"{0}\"=\"{1}\"]' -f $propName,$defValue | Write-Verbose\n                $publishProperties[\"$propName\"] = $defValue\n            }\n        }\n\n        if($publishProperties['MSDeployUseChecksum'] -eq $true){\n            $sharedArgs.ExtraArgs += '-usechecksum'\n        }\n\n        if($publishProperties['EnableMSDeployAppOffline'] -eq $true){\n            $sharedArgs.ExtraArgs += '-enablerule:AppOffline'\n        }\n\n        if($publishProperties['WebPublishMethod'] -eq 'MSDeploy'){           \n            if($publishProperties['SkipExtraFilesOnServer'] -eq $true){\n                $sharedArgs.ExtraArgs += '-enableRule:DoNotDeleteRule'\n            }\n        }\n\n        if($publishProperties['WebPublishMethod'] -eq 'FileSystem'){\n            if($publishProperties['DeleteExistingFiles'] -eq $false){\n                $sharedArgs.ExtraArgs += '-enableRule:DoNotDeleteRule'\n            }\n        }\n\n        if($publishProperties['retryAttempts']){\n            $sharedArgs.ExtraArgs += ('-retryAttempts:{0}' -f ([int]$publishProperties['retryAttempts']))\n        }\n\n        if($publishProperties['EncryptWebConfig'] -eq $true){\n            $sharedArgs.ExtraArgs += '-EnableRule:EncryptWebConfig'\n        }\n\n        if($publishProperties['EnableMSDeployBackup'] -eq $false){\n            $sharedArgs.ExtraArgs += '-disablerule:BackupRule'\n        }\n\n        if($publishProperties['AllowUntrustedCertificate'] -eq $true){\n            $sharedArgs.ExtraArgs += '-allowUntrusted'\n        }\n\n        # add excludes\n        $sharedArgs.ExtraArgs += (GetInternal-ExcludeFilesArg -publishProperties $publishProperties)\n        # add replacements\n        $sharedArgs.ExtraArgs += (GetInternal-ReplacementsMSDeployArgs -publishProperties $publishProperties)\n\n        # add EF Migration\n        if (($publishProperties['EfMigrations'] -ne $null) -and $publishProperties['EfMigrations'].Count -gt 0){\n            if (!(Test-Path -Path $publishProperties['ProjectPath'])) {\n                throw 'ProjectPath property needs to be defined in the pubxml for EF migration.'\n            }\n            try {\n                # generate T-SQL files\n                $EFSqlFiles = GenerateInternal-EFMigrationScripts -projectPath $publishProperties['ProjectPath'] -packOutput $packOutput -EFMigrations $publishProperties['EfMigrations']\n                $sharedArgs.EFMigrationData.Add('EFSqlFiles',$EFSqlFiles)\n            }\n            catch {\n                throw ('An error occurred while generating EF migrations. {0} {1}' -f $_.Exception,(Get-PSCallStack))\n            }\n        }\n        # add connection string update\n        if (($publishProperties['DestinationConnectionStrings'] -ne $null) -and $publishProperties['DestinationConnectionStrings'].Count -gt 0) {\n            try {\n                # create/update appsettings.[environment].json\n                GenerateInternal-AppSettingsFile -packOutput $packOutput -environmentName $publishProperties['EnvironmentName'] -connectionStrings $publishProperties['DestinationConnectionStrings']\n            }\n            catch {\n                throw ('An error occurred while generating the publish appsettings file. {0} {1}' -f $_.Exception,(Get-PSCallStack))\n            }\n        }\n\n        if(-not [string]::IsNullOrWhiteSpace($publishProperties['ProjectGuid'])) {\n            AddInternal-ProjectGuidToWebConfig -publishProperties $publishProperties -packOutput $packOutput\n        }\n\n        # return the args\n        $sharedArgs\n    }\n}\n\n<#\n.SYNOPSIS\nThis will publish the folder based on the properties in $publishProperties\n\n.PARAMETER publishProperties\nThis is a hashtable containing the publish properties. See the examples here for more info on how to use this parameter.\n\n.PARAMETER packOutput\nThe folder path to the output of the dnu publish command. This folder contains the files\nthat will be published.\n\n.PARAMETER pubProfilePath\nPath to a publish profile (.pubxml file) to import publish properties from. If the same property exists in\npublishProperties and the publish profile then publishProperties will win.\n\n.EXAMPLE\n Publish-AspNet -packOutput $packOutput -publishProperties @{\n     'WebPublishMethod'='MSDeploy'\n     'MSDeployServiceURL'='contoso.scm.azurewebsites.net:443';`\n     'DeployIisAppPath'='contoso';'Username'='$contoso';'Password'=\"$env:PublishPwd\"}\n\n.EXAMPLE\nPublish-AspNet -packOutput $packOutput -publishProperties @{\n    'WebPublishMethod'='FileSystem'\n    'publishUrl'=\"$publishDest\"\n    }\n\n.EXAMPLE\nPublish-AspNet -packOutput $packOutput -publishProperties @{\n     'WebPublishMethod'='MSDeploy'\n     'MSDeployServiceURL'='contoso.scm.azurewebsites.net:443';`\n'DeployIisAppPath'='contoso';'Username'='$contoso';'Password'=\"$env:PublishPwd\"\n    'ExcludeFiles'=@(\n        @{'absolutepath'='test.txt'},\n        @{'absolutepath'='references.js'}\n)} \n\n.EXAMPLE\nPublish-AspNet -packOutput $packOutput -publishProperties @{\n    'WebPublishMethod'='FileSystem'\n    'publishUrl'=\"$publishDest\"\n    'ExcludeFiles'=@(\n        @{'absolutepath'='test.txt'},\n        @{'absolutepath'='_references.js'})\n    'Replacements' = @(\n        @{'file'='test.txt$';'match'='REPLACEME';'newValue'='updatedValue'})\n    }\n\nPublish-AspNet -packOutput $packOutput -publishProperties @{\n    'WebPublishMethod'='FileSystem'\n    'publishUrl'=\"$publishDest\"\n    'ExcludeFiles'=@(\n        @{'absolutepath'='test.txt'},\n        @{'absolutepath'='c:\\\\full\\\\path\\\\ok\\\\as\\\\well\\\\_references.js'})\n    'Replacements' = @(\n        @{'file'='test.txt$';'match'='REPLACEME';'newValue'='updatedValue'})\n    }\n\n.EXAMPLE\nPublish-AspNet -packOutput $packOutput -publishProperties @{\n    'WebPublishMethod'='FileSystem'\n    'publishUrl'=\"$publishDest\"\n    'EnableMSDeployAppOffline'='true'\n    'AppOfflineTemplate'='offline-template.html'\n    'MSDeployUseChecksum'='true'\n}\n#>\nfunction Publish-AspNet{\n    param(\n        [Parameter(Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]\n        [hashtable]$publishProperties = @{},\n\n        [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)]\n        [System.IO.FileInfo]$packOutput,\n\n        [Parameter(Position=2,ValueFromPipelineByPropertyName=$true)]\n        [System.IO.FileInfo]$pubProfilePath\n    )\n    process{\n        if($publishProperties['WebPublishMethodOverride']){\n            'Overriding publish method from $publishProperties[''WebPublishMethodOverride''] to [{0}]' -f  ($publishProperties['WebPublishMethodOverride']) | Write-Verbose\n            $publishProperties['WebPublishMethod'] = $publishProperties['WebPublishMethodOverride']\n        }\n\n        if(-not [string]::IsNullOrWhiteSpace($pubProfilePath)){\n            $profileProperties = Get-PropertiesFromPublishProfile -filepath $pubProfilePath\n            foreach($key in $profileProperties.Keys){\n                if(-not ($publishProperties.ContainsKey($key))){\n                    'Adding properties from publish profile [''{0}''=''{1}'']' -f $key,$profileProperties[$key] | Write-Verbose\n                    $publishProperties.Add($key,$profileProperties[$key])\n                }\n            }\n        }\n\n        if(!([System.IO.Path]::IsPathRooted($packOutput))){\n            $packOutput = [System.IO.Path]::GetFullPath((Join-Path $pwd $packOutput))\n        }\n\n        $pubMethod = $publishProperties['WebPublishMethod']\n        'Publishing with publish method [{0}]' -f $pubMethod | Write-Output\n\n        # get the handler based on WebPublishMethod, and call it.\n        &(Get-AspnetPublishHandler -name $pubMethod) $publishProperties $packOutput\n    }\n}\n\n<#\n.SYNOPSIS\n\nInputs:\n\nExample of $xmlDocument: '<?xml version=\"1.0\" encoding=\"utf-8\"?><sitemanifest></sitemanifest>'\nExample of $providerDataArray:\n\n    [System.Collections.ArrayList]$providerDataArray = @()\n\n    $iisAppSourceKeyValue=@{\"iisApp\" = @{\"path\"='c:\\temp\\pathtofiles';\"appOfflineTemplate\" ='offline-template.html'}}\n    $providerDataArray.Add($iisAppSourceKeyValue)\n\n    $dbfullsqlKeyValue=@{\"dbfullsql\" = @{\"path\"=\"c:\\Temp\\PathToSqlFile\"}}\n    $providerDataArray.Add($dbfullsqlKeyValue)\n\n    $dbfullsqlKeyValue=@{\"dbfullsql\" = @{\"path\"=\"c:\\Temp\\PathToSqlFile2\"}}\n    $providerDataArray.Add($dbfullsqlKeyValue)\n\n    Manifest File content:\n            <?xml version=\"1.0\" encoding=\"utf-8\"?>\n            <sitemanifest>\n            <iisApp path=\"c:\\temp\\pathtofiles\" appOfflineTemplate=�offline-template.html\" />\n            <dbFullSql path=\"c:\\Temp\\PathToSqlFile\" />\n            <dbFullSql path=\"c:\\Temp\\PathToSqlFile2\" />\n            </sitemanifest>\n#>\nfunction AddInternal-ProviderDataToManifest {\n    [cmdletbinding()]\n    param(\n        [Parameter(Mandatory=$true, Position=0)]\n        [XML]$xmlDocument,\n        [Parameter(Position=1)]\n        [System.Collections.ArrayList]$providerDataArray\n    )\n    process {\n        $siteNode = $xmlDocument.SelectSingleNode(\"/sitemanifest\")\n        if ($siteNode -eq $null) {\n            throw 'sitemanifest element is missing in the xml object'\n        }\n        foreach ($providerData in $providerDataArray) {\n            foreach ($providerName in $providerData.Keys) {\n                $providerValue = $providerData[$providerName]\n                $xmlNode = $xmlDocument.CreateElement($providerName)\n                foreach ($providerValueKey in $providerValue.Keys) {\n                    $xmlNode.SetAttribute($providerValueKey, $providerValue[$providerValueKey]) | Out-Null\n                }\n                $siteNode.AppendChild($xmlNode) | Out-Null \n            }\n        }\n    }\n} \n\nfunction AddInternal-ProjectGuidToWebConfig {\n    [cmdletbinding()]\n    param(\n        [Parameter(Position=0)]\n        [HashTable]$publishProperties,\n        [Parameter(Position=1)]\n        [System.IO.FileInfo]$packOutput\n    )\n    process {\n        try {\n            [Reflection.Assembly]::LoadWithPartialName(\"System.Xml.Linq\") | Out-Null\n            $webConfigPath = Join-Path $packOutput 'web.config'\n            $projectGuidCommentValue = 'ProjectGuid: {0}' -f $publishProperties['ProjectGuid']\n            $xDoc = [System.Xml.Linq.XDocument]::Load($webConfigPath)\n            $allNodes = $xDoc.DescendantNodes() \n            $projectGuidComment = $allNodes | Where-Object { $_.NodeType -eq [System.Xml.XmlNodeType]::Comment -and $_.Value -eq $projectGuidCommentValue } | Select -First 1    \n            if($projectGuidComment -ne $null) {\n                if($publishProperties['IgnoreProjectGuid'] -eq $true) {\n                   $projectGuidComment.Remove() | Out-Null\n                   $xDoc.Save($webConfigPath) | Out-Null\n                }\n            }\n            else {\n                if(-not ($publishProperties['IgnoreProjectGuid'] -eq $true)) {\n                   $projectGuidComment = New-Object -TypeName System.Xml.Linq.XComment -ArgumentList $projectGuidCommentValue\n                   $xDoc.LastNode.AddAfterSelf($projectGuidComment) | Out-Null\n                   $xDoc.Save($webConfigPath) | Out-Null\n                }\n            }\n        }\n        catch {\n        }\n    }\n}\n\n<#\n.SYNOPSIS\n\nExample of $EFMigrations:\n            $EFMigrations = @{'CarContext'='Car Context ConnectionString';'MovieContext'='Movie Context Connection String'}\n\n#>\n\nfunction GenerateInternal-EFMigrationScripts {\n    [cmdletbinding()]\n    param(\n        [Parameter(Mandatory=$true,Position=0)]\n        [System.IO.FileInfo]$projectPath,\n        [Parameter(Mandatory=$true,Position=1)]\n        [System.IO.FileInfo]$packOutput,\n        [Parameter(Position=2)]\n        [HashTable]$EFMigrations\n    )\n    process {          \n        $files = @{}\n        $dotnetExePath = GetInternal-DotNetExePath\n        foreach ($dbContextName in $EFMigrations.Keys) {\n            try \n            {\n                $tempDir = GetInternal-PublishTempPath -packOutput $packOutput\n                $efScriptFile = Join-Path $tempDir ('{0}.sql' -f $dbContextName)\n                $arg = ('ef migrations script --idempotent --output {0} --context {1}' -f\n                                       $efScriptFile,\n                                       $dbContextName)\n\n                Execute-Command $dotnetExePath $arg $projectPath | Out-Null\n                if (Test-Path -Path $efScriptFile) {\n                    if (!($files.ContainsKey($dbContextName))) {\n                        $files.Add($dbContextName, $efScriptFile) | Out-Null\n                    }\n                }            \n            }\n            catch\n            {\n                throw 'error occured when executing dotnet.exe to generate EF T-SQL file'\n            }\n        }\n        # return files object\n        $files\n    }\n}\n\n<#\n.SYNOPSIS\n\nExample of $connectionStrings:\n            $connectionStrings = @{'DefaultConnection'='Default ConnectionString';'CarConnection'='Car Connection String'}\n\n#>\nfunction GenerateInternal-AppSettingsFile {\n    [cmdletbinding()]\n    param(\n        [Parameter(Mandatory = $true,Position=0)]\n        [System.IO.FileInfo]$packOutput,\n        [Parameter(Mandatory = $true,Position=1)]\n        [string]$environmentName,\n        [Parameter(Position=2)]\n        [HashTable]$connectionStrings\n    )\n    process {    \n        $configProdJsonFile = 'appsettings.{0}.json' -f $environmentName\n        $configProdJsonFilePath = Join-Path -Path $packOutput -ChildPath $configProdJsonFile \n\n        if ([string]::IsNullOrEmpty($configProdJsonFilePath)) {\n            throw ('The path of {0} is empty' -f $configProdJsonFilePath)\n        }\n        \n        if(!(Test-Path -Path $configProdJsonFilePath)) {\n            # create new file\n            '{}' | out-file -encoding utf8 -filePath $configProdJsonFilePath -Force\n        }\n        \n        $jsonObj = ConvertFrom-Json -InputObject (Get-Content -Path $configProdJsonFilePath -Raw)\n        # update when there exists one or more connection strings\n        if ($connectionStrings -ne $null) {            \n            foreach ($name in $connectionStrings.Keys) {\n                #check for hierarchy style\n                if ($jsonObj.ConnectionStrings.$name) {\n                    $jsonObj.ConnectionStrings.$name = $connectionStrings[$name]\n                    continue\n                }\n                #check for horizontal style\n                $horizontalName = 'ConnectionStrings.{0}:' -f $name\n                if ($jsonObj.$horizontalName) {\n                    $jsonObj.$horizontalName = $connectionStrings[$name]\n                    continue\n                }\n                # create new one\n                if (!($jsonObj.ConnectionStrings)) {\n                    $contentForDefaultConnection = '{}'\n                    $jsonObj | Add-Member -name 'ConnectionStrings' -value (ConvertFrom-Json -InputObject $contentForDefaultConnection) -MemberType NoteProperty | Out-Null\n                }\n                if (!($jsonObj.ConnectionStrings.$name)) {\n                    $jsonObj.ConnectionStrings | Add-Member -name $name -value $connectionStrings[$name] -MemberType NoteProperty | Out-Null\n                }\n            }            \n        }\n        \n        $jsonObj | ConvertTo-Json | out-file -encoding utf8 -filePath $configProdJsonFilePath -Force\n          \n        #return the path of config.[environment].json\n        $configProdJsonFilePath\n    }\n}\n\n<#\n.SYNOPSIS\n\nInputs:\nExample of $providerDataArray:\n\n    [System.Collections.ArrayList]$providerDataArray = @()\n\n    $iisAppSourceKeyValue=@{\"iisApp\" = @{\"path\"='c:\\temp\\pathtofiles';\"appOfflineTemplate\" ='offline-template.html'}}\n    $providerDataArray.Add($iisAppSourceKeyValue)\n\n    $dbfullsqlKeyValue=@{\"dbfullsql\" = @{\"path\"=\"c:\\Temp\\PathToSqlFile\"}}\n    $providerDataArray.Add($dbfullsqlKeyValue)\n\n    $dbfullsqlKeyValue=@{\"dbfullsql\" = @{\"path\"=\"c:\\Temp\\PathToSqlFile2\"}}\n    $providerDataArray.Add($dbfullsqlKeyValue)\n\n    Manifest File content:\n        <?xml version=\"1.0\" encoding=\"utf-8\"?>\n        <sitemanifest>\n        <iisApp path=\"c:\\temp\\pathtofiles\" appOfflineTemplate=�offline-template.html\" />\n        <dbFullSql path=\"c:\\Temp\\PathToSqlFile\" />\n        <dbFullSql path=\"c:\\Temp\\PathToSqlFile2\" />\n        </sitemanifest>\n\n#>\n\nfunction GenerateInternal-ManifestFile {\n    [cmdletbinding()]\n    param(\n        [Parameter(Mandatory=$true,Position=0)]\n        [System.IO.FileInfo]$packOutput,\n        [Parameter(Mandatory=$true,Position=1)]\n        $publishProperties,\n        [Parameter(Mandatory=$true,Position=2)]\n        [System.Collections.ArrayList]$providerDataArray,\n        [Parameter(Mandatory=$true,Position=3)]\n        [ValidateNotNull()]\n        $manifestFileName\n    )\n    process{\n        $xmlDocument = [xml]'<?xml version=\"1.0\" encoding=\"utf-8\"?><sitemanifest></sitemanifest>'\n        AddInternal-ProviderDataToManifest -xmlDocument $xmlDocument -providerDataArray $providerDataArray | Out-Null\n        $publishTempDir = GetInternal-PublishTempPath -packOutput $packOutput\n        $XMLFile = Join-Path $publishTempDir $manifestFileName\n        $xmlDocument.OuterXml | out-file -encoding utf8 -filePath $XMLFile -Force\n        \n        # return \n        [System.IO.FileInfo]$XMLFile\n    }\n}\n\nfunction GetInternal-PublishTempPath {\n    [cmdletbinding()]\n    param(\n        [Parameter(Mandatory=$true, Position=0)]\n        [System.IO.FileInfo]$packOutput\n    )\n    process {\n        $tempDir = [io.path]::GetTempPath()\n        $packOutputFolderName = Split-Path $packOutput -Leaf\n        $publishTempDir = [io.path]::combine($tempDir,'PublishTemp','obj',$packOutputFolderName)\n        if (!(Test-Path -Path $publishTempDir)) {\n            New-Item -Path $publishTempDir -type directory | Out-Null\n        }\n        # return \n        [System.IO.FileInfo]$publishTempDir\n    }\n}\n\nfunction Publish-AspNetMSDeploy{\n    param(\n        [Parameter(Mandatory = $true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]\n        $publishProperties,\n        [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)]\n        $packOutput\n    )\n    process{\n        if($publishProperties){\n            $publishPwd = $publishProperties['Password']\n            \n            $sharedArgs = GetInternal-SharedMSDeployParametersFrom -publishProperties $publishProperties -packOutput $packOutput\n            $iisAppPath = $publishProperties['DeployIisAppPath']\n            \n            # create source manifest\n\n            # e.g\n            # <?xml version=\"1.0\" encoding=\"utf-8\"?>\n            # <sitemanifest>\n            # <iisApp path=\"C:\\Temp\\PublishTemp\\WebApplication\\\" appOfflineTemplate=�offline-template.html\" />\n            # <dbFullSql path=\"C:\\Temp\\PublishTemp\\obj\\WebApplication.Data.ApplicationDbContext.sql\" />\n            # <dbFullSql path=\"C:\\Temp\\PublishTemp\\obj\\WebApplication.Data.CarContext.sql\" />\n            # </sitemanifest>\n\n            [System.Collections.ArrayList]$providerDataArray = @()\n            $iisAppValues = @{\"path\"=$packOutput};\n            $iisAppSourceKeyValue=@{\"iisApp\" = $iisAppValues}\n            $providerDataArray.Add($iisAppSourceKeyValue) | Out-Null\n\n            if ($sharedArgs.EFMigrationData -ne $null -and $sharedArgs.EFMigrationData.Contains('EFSqlFiles')) { \n                foreach ($sqlFile in $sharedArgs.EFMigrationData['EFSqlFiles'].Values) { \n                    $dbFullSqlSourceKeyValue=@{\"dbFullSql\" = @{\"path\"=$sqlFile}}\n                    $providerDataArray.Add($dbFullSqlSourceKeyValue) | Out-Null       \n                }\n            }\n            \n            [System.IO.FileInfo]$sourceXMLFile = GenerateInternal-ManifestFile -packOutput $packOutput -publishProperties $publishProperties -providerDataArray $providerDataArray -manifestFileName 'SourceManifest.xml'\n            \n            $providerDataArray.Clear() | Out-Null\n            # create destination manifest   \n\n            # e.g\n            # <?xml version=\"1.0\" encoding=\"utf-8\"?>\n            # <sitemanifest><iisApp path=\"WebApplication8020160609015407\" />\n            # <dbFullSql path=\"Data Source=tcp:webapplicationdbserver.database.windows.net,1433;Initial Catalog=WebApplication_db;User Id=sqladmin@webapplicationdbserver;Password=<password>\" />\n            # <dbFullSql path=\"Data Source=tcp:webapplicationdbserver.database.windows.net,1433;Initial Catalog=WebApplication_db;User Id=sqladmin@webapplicationdbserver;Password=<password>\" />\n            # </sitemanifest>\n\n            $iisAppValues = @{\"path\"=$iisAppPath};\n            if(-not [string]::IsNullOrWhiteSpace($publishProperties['AppOfflineTemplate'])){\n                $iisAppValues.Add(\"appOfflineTemplate\", $publishProperties['AppOfflineTemplate']) | Out-Null\n            }\n\n            $iisAppDestinationKeyValue=@{\"iisApp\" = $iisAppValues}\n            $providerDataArray.Add($iisAppDestinationKeyValue) | Out-Null\n\n            if ($publishProperties['EfMigrations'] -ne $null -and $publishProperties['EfMigrations'].Count -gt 0) { \n                foreach ($connectionString in $publishProperties['EfMigrations'].Values) { \n                    $dbFullSqlDestinationKeyValue=@{\"dbFullSql\" = @{\"path\"=$connectionString}}\n                    $providerDataArray.Add($dbFullSqlDestinationKeyValue) | Out-Null       \n                }\n            }\n\n\n            [System.IO.FileInfo]$destXMLFile = GenerateInternal-ManifestFile -packOutput $packOutput -publishProperties $publishProperties -providerDataArray $providerDataArray -manifestFileName 'DestinationManifest.xml'\n  \n            <#\n            \"C:\\Program Files (x86)\\IIS\\Microsoft Web Deploy V3\\msdeploy.exe\" \n                -source:manifest='C:\\Users\\testuser\\AppData\\Local\\Temp\\PublishTemp\\obj\\SourceManifest.xml' \n                -dest:manifest='C:\\Users\\testuser\\AppData\\Local\\Temp\\PublishTemp\\obj\\DestManifest.xml',ComputerName='https://contoso.scm.azurewebsites.net/msdeploy.axd',UserName='$contoso',Password='<PWD>',IncludeAcls='False',AuthType='Basic' \n                -verb:sync \n                -enableRule:DoNotDeleteRule \n                -retryAttempts=2\"\n            #>\n\n            if(-not [string]::IsNullOrWhiteSpace($publishProperties['MSDeployPublishMethod'])){\n                $serviceMethod = $publishProperties['MSDeployPublishMethod']\n            }\n            \n            $msdeployComputerName= InternalNormalize-MSDeployUrl -serviceUrl $publishProperties['MSDeployServiceURL'] -siteName $iisAppPath -serviceMethod $publishProperties['MSDeployPublishMethod']\n            if($publishProperties['UseMSDeployServiceURLAsIs'] -eq $true){\n               $msdeployComputerName = $publishProperties['MSDeployServiceURL']\n            }\n\n            $publishArgs = @()\n            #use manifest to publish\n            $publishArgs += ('-source:manifest=''{0}''' -f $sourceXMLFile.FullName)\n            $publishArgs += ('-dest:manifest=''{0}'',ComputerName=''{1}'',UserName=''{2}'',Password=''{3}'',IncludeAcls=''False'',AuthType=''{4}''{5}' -f \n                                    $destXMLFile.FullName,\n                                    $msdeployComputerName,\n                                    $publishProperties['UserName'],\n                                    $publishPwd,\n                                    $publishProperties['AuthType'],\n                                    $sharedArgs.DestFragment)\n            $publishArgs += '-verb:sync'\n            $publishArgs += $sharedArgs.ExtraArgs\n\n            $command = '\"{0}\" {1}' -f (Get-MSDeploy),($publishArgs -join ' ')\n            \n            if (! [String]::IsNullOrEmpty($publishPwd)) {\n            $command.Replace($publishPwd,'{PASSWORD-REMOVED-FROM-LOG}') | Print-CommandString\n            }\n            Execute-Command -exePath (Get-MSDeploy) -arguments ($publishArgs -join ' ')\n        }\n        else{\n            throw 'publishProperties is empty, cannot publish'\n        }\n    }\n}\n\nfunction Escape-TextForRegularExpressions{\n    [cmdletbinding()]\n    param(\n        [Parameter(Position=0,Mandatory=$true)]\n        [string]$text\n    )\n    process{\n        [regex]::Escape($text)\n    }\n}\n\nfunction Publish-AspNetMSDeployPackage{\n    param(\n        [Parameter(Mandatory = $true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]\n        $publishProperties,\n        [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)]\n        $packOutput\n    )\n    process{\n        if($publishProperties){\n            $packageDestinationFilepath = $publishProperties['DesktopBuildPackageLocation']\n\n            if(!$packageDestinationFilepath){\n                throw ('The package destination property (DesktopBuildPackageLocation) was not found in the publish properties')\n            }\n\n            if(!([System.IO.Path]::IsPathRooted($packageDestinationFilepath))){\n                $packageDestinationFilepath = [System.IO.Path]::GetFullPath((Join-Path $pwd $packageDestinationFilepath))\n            }\n\n            # if the dir doesn't exist create it\n            $pkgDir = ((new-object -typename System.IO.FileInfo($packageDestinationFilepath)).Directory)\n            if(!(Test-Path -Path $pkgDir)) {\n                New-Item $pkgDir -type Directory | Out-Null\n            }\n\n            <#\n            \"C:\\Program Files (x86)\\IIS\\Microsoft Web Deploy V3\\msdeploy.exe\" \n                -source:manifest='C:\\Users\\testuser\\AppData\\Local\\Temp\\PublishTemp\\obj\\SourceManifest.xml'\n                -dest:package=c:\\temp\\path\\contosoweb.zip\n                -verb:sync \n                -enableRule:DoNotDeleteRule  \n                -retryAttempts=2 \n            #>\n\n            $sharedArgs = GetInternal-SharedMSDeployParametersFrom -publishProperties $publishProperties -packOutput $packOutput\n\n            # create source manifest\n\n            # e.g\n            # <?xml version=\"1.0\" encoding=\"utf-8\"?>\n            # <sitemanifest>\n            # <iisApp path=\"C:\\Temp\\PublishTemp\\WebApplication\\\" />\n            # </sitemanifest>\n\n            [System.Collections.ArrayList]$providerDataArray = @()\n            $iisAppSourceKeyValue=@{\"iisApp\" = @{\"path\"=$packOutput}}\n            $providerDataArray.Add($iisAppSourceKeyValue) | Out-Null\n\n            [System.IO.FileInfo]$sourceXMLFile = GenerateInternal-ManifestFile -packOutput $packOutput -publishProperties $publishProperties -providerDataArray $providerDataArray -manifestFileName 'SourceManifest.xml' \n\n            $publishArgs = @()\n            $publishArgs += ('-source:manifest=''{0}''' -f $sourceXMLFile.FullName)\n            $publishArgs += ('-dest:package=''{0}''' -f $packageDestinationFilepath)\n            $publishArgs += '-verb:sync'\n            $packageContentFolder = $publishProperties['MSDeployPackageContentFoldername']\n            if(!$packageContentFolder){ $packageContentFolder = 'website' }\n            $publishArgs += ('-replace:match=''{0}'',replace=''{1}''' -f (Escape-TextForRegularExpressions $packOutput), $packageContentFolder )\n            $publishArgs += $sharedArgs.ExtraArgs\n            \n            $command = '\"{0}\" {1}' -f (Get-MSDeploy),($publishArgs -join ' ')\n            $command | Print-CommandString\n            Execute-Command -exePath (Get-MSDeploy) -arguments ($publishArgs -join ' ')\n        }\n        else{\n            throw 'publishProperties is empty, cannot publish'\n        }\n    }\n}\n\nfunction Publish-AspNetFileSystem{\n    param(\n        [Parameter(Mandatory = $true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]\n        $publishProperties,\n        [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)]\n        $packOutput\n    )\n    process{\n        $pubOut = $publishProperties['publishUrl']\n        \n        if([string]::IsNullOrWhiteSpace($pubOut)){\n            throw ('publishUrl is a required property for FileSystem publish but it was empty.')\n        }\n\n        # if it's a relative path then update it to a full path\n        if(!([System.IO.Path]::IsPathRooted($pubOut))){\n            $pubOut = [System.IO.Path]::GetFullPath((Join-Path $pwd $pubOut))\n            $publishProperties['publishUrl'] = \"$pubOut\"\n        }\n\n        'Publishing files to {0}' -f $pubOut | Write-Output\n\n        # we use msdeploy.exe because it supports incremental publish/skips/replacements/etc\n        # msdeploy.exe -verb:sync -source:manifest='C:\\Users\\testuser\\AppData\\Local\\Temp\\PublishTemp\\obj\\SourceManifest.xml' -dest:manifest='C:\\Users\\testuser\\AppData\\Local\\Temp\\PublishTemp\\obj\\DestManifest.xml'\n        \n        $sharedArgs = GetInternal-SharedMSDeployParametersFrom -publishProperties $publishProperties -packOutput $packOutput\n\n        # create source manifest\n\n        # e.g\n        # <?xml version=\"1.0\" encoding=\"utf-8\"?>\n        # <sitemanifest>\n        # <contentPath path=\"C:\\Temp\\PublishTemp\\WebApplication\\\" appOfflineTemplate=�offline-template.html\" />\n        # </sitemanifest>\n\n        [System.Collections.ArrayList]$providerDataArray = @()\n        $contentPathValues = @{\"path\"=$packOutput};\n        $contentPathSourceKeyValue=@{\"contentPath\" = $contentPathValues}\n        $providerDataArray.Add($contentPathSourceKeyValue) | Out-Null\n            \n        [System.IO.FileInfo]$sourceXMLFile = GenerateInternal-ManifestFile -packOutput $packOutput -publishProperties $publishProperties -providerDataArray $providerDataArray -manifestFileName 'SourceManifest.xml'\n            \n        $providerDataArray.Clear() | Out-Null\n        # create destination manifest   \n\n        # e.g\n        # <?xml version=\"1.0\" encoding=\"utf-8\"?>\n        # <sitemanifest><contentPath path=\"C:\\Temp\\PublishTemp\\WebApplicationDestination\\\" />\n        # </sitemanifest>\n        $contentPathValues = @{\"path\"=$publishProperties['publishUrl']};\n        if(-not [string]::IsNullOrWhiteSpace($publishProperties['AppOfflineTemplate'])){\n            $contentPathValues.Add(\"appOfflineTemplate\", $publishProperties['AppOfflineTemplate']) | Out-Null\n        }\n        $contentPathDestinationKeyValue=@{\"contentPath\" = $contentPathValues}\n        $providerDataArray.Add($contentPathDestinationKeyValue) | Out-Null\n\n        [System.IO.FileInfo]$destXMLFile = GenerateInternal-ManifestFile -packOutput $packOutput -publishProperties $publishProperties -providerDataArray $providerDataArray -manifestFileName 'DestinationManifest.xml'\n        \n        $publishArgs = @()\n        $publishArgs += ('-source:manifest=''{0}''' -f $sourceXMLFile.FullName)\n        $publishArgs += ('-dest:manifest=''{0}''{1}' -f $destXMLFile.FullName, $sharedArgs.DestFragment)\n        $publishArgs += '-verb:sync'\n        $publishArgs += $sharedArgs.ExtraArgs\n\n        $command = '\"{0}\" {1}' -f (Get-MSDeploy),($publishArgs -join ' ')\n        $command | Print-CommandString\n        Execute-Command -exePath (Get-MSDeploy) -arguments ($publishArgs -join ' ')\n        \n        # copy sql script to script folder\n        if (($sharedArgs.EFMigrationData['EFSqlFiles'] -ne $null) -and ($sharedArgs.EFMigrationData['EFSqlFiles'].Count -gt 0)) {\n            $scriptsDir = Join-Path $pubOut 'efscripts'\n\n            if (!(Test-Path -Path $scriptsDir)) {\n                New-Item -Path $scriptsDir -type directory | Out-Null\n            }\n\n            foreach ($sqlFile in $sharedArgs.EFMigrationData['EFSqlFiles'].Values) {\n                Copy-Item $sqlFile -Destination $scriptsDir -Force -Recurse | Out-Null\n            }\n        }\n    }\n}\n\n<#\n.SYNOPSIS\n    This can be used to read a publish profile to extract the property values into a hashtable.\n\n.PARAMETER filepath\n    Path to the publish profile to get the properties from. Currenlty this only supports reading\n    .pubxml files.\n\n.EXAMPLE\n    Get-PropertiesFromPublishProfile -filepath c:\\projects\\publish\\devpublish.pubxml\n#>\nfunction Get-PropertiesFromPublishProfile{\n    [cmdletbinding()]\n    param(\n        [Parameter(Position=0,Mandatory=$true)]\n        [ValidateNotNull()]\n        [ValidateScript({Test-Path $_})]\n        [System.IO.FileInfo]$filepath\n    )\n    begin{\n        Add-Type -AssemblyName System.Core\n        Add-Type -AssemblyName Microsoft.Build\n    }\n    process{\n        'Reading publish properties from profile [{0}]' -f $filepath | Write-Verbose\n        # use MSBuild to get the project and read properties\n        $projectCollection = (New-Object Microsoft.Build.Evaluation.ProjectCollection)\n        if(!([System.IO.Path]::IsPathRooted($filepath))){\n            $filepath = [System.IO.Path]::GetFullPath((Join-Path $pwd $filepath))\n        }\n        $project = ([Microsoft.Build.Construction.ProjectRootElement]::Open([string]$filepath.Fullname, $projectCollection))\n\n        $properties = @{}\n        foreach($property in $project.Properties){\n            $properties[$property.Name]=$property.Value\n        }\n\n        $properties\n    }\n}\n\nfunction Print-CommandString{\n    [cmdletbinding()]\n    param(\n        [Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true)]\n        $command\n    )\n    process{\n        'Executing command [{0}]' -f $command | Write-Output\n    }\n}\n\nfunction Execute-CommandString{\n    [cmdletbinding()]\n    param(\n        [Parameter(Mandatory=$true,Position=0,ValueFromPipeline=$true)]\n        [string[]]$command,\n        \n        [switch]\n        $useInvokeExpression,\n\n        [switch]\n        $ignoreErrors\n    )\n    process{\n        foreach($cmdToExec in $command){\n            'Executing command [{0}]' -f $cmdToExec | Write-Verbose\n            if($useInvokeExpression){\n                try {\n                    Invoke-Expression -Command $cmdToExec\n                }\n                catch {\n                    if(-not $ignoreErrors){\n                        $msg = ('The command [{0}] exited with exception [{1}]' -f $cmdToExec, $_.ToString())\n                        throw $msg\n                    }\n                }\n            }\n            else {\n                cmd.exe /D /C $cmdToExec\n\n                if(-not $ignoreErrors -and ($LASTEXITCODE -ne 0)){\n                    $msg = ('The command [{0}] exited with code [{1}]' -f $cmdToExec, $LASTEXITCODE)\n                    throw $msg\n                }\n            }\n        }\n    }\n}\n\nfunction Execute-Command {\n    [cmdletbinding()]\n    param(\n        [Parameter(Mandatory = $true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]\n        [String]$exePath,\n        [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)]\n        [String]$arguments,\n        [Parameter(Position=2)]\n        [System.IO.FileInfo]$workingDirectory\n        )\n    process{\n        $psi = New-Object -TypeName System.Diagnostics.ProcessStartInfo\n        $psi.CreateNoWindow = $true\n        $psi.UseShellExecute = $false\n        $psi.RedirectStandardOutput = $true\n        $psi.RedirectStandardError=$true\n        $psi.FileName = $exePath\n        $psi.Arguments = $arguments\n        if($workingDirectory -and (Test-Path -Path $workingDirectory)) {\n            $psi.WorkingDirectory = $workingDirectory\n        }\n\n        $process = New-Object -TypeName System.Diagnostics.Process\n        $process.StartInfo = $psi\n        $process.EnableRaisingEvents=$true\n\n        # Register the event handler for error\n        $stdErrEvent = Register-ObjectEvent -InputObject $process  -EventName 'ErrorDataReceived' -Action {\n            if (! [String]::IsNullOrEmpty($EventArgs.Data)) {\n             $EventArgs.Data | Write-Error \n            }\n        }\n\n        # Starting process.\n        $process.Start() | Out-Null\n        $process.BeginErrorReadLine() | Out-Null\n        $output = $process.StandardOutput.ReadToEnd()\n        $process.WaitForExit() | Out-Null\n        $output | Write-Output\n        \n        # UnRegister the event handler for error\n        Unregister-Event -SourceIdentifier $stdErrEvent.Name | Out-Null\n    }\n}\n\n\nfunction GetInternal-DotNetExePath {\n    process {\n        $dotnetinstallpath = $env:dotnetinstallpath\n        if (!$dotnetinstallpath) {\n            $DotNetRegItem = Get-ItemProperty -Path 'hklm:\\software\\dotnet\\setup\\'\n            if ($env:DOTNET_HOME) {\n                $dotnetinstallpath = Join-Path $env:DOTNET_HOME -ChildPath 'dotnet.exe'\n            }\n            elseif ($DotNetRegItem -and $DotNetRegItem.InstallDir){\n                $dotnetinstallpath = Join-Path $DotNetRegItem.InstallDir -ChildPath 'dotnet.exe'\n            }\n        }\n        if (!(Test-Path $dotnetinstallpath)) {\n            throw 'Unable to find dotnet.exe, please install it and try again'\n        }\n        # return\n        [System.IO.FileInfo]$dotnetinstallpath\n    }\n}\n\nfunction Get-MSDeploy{\n    [cmdletbinding()]\n    param()\n    process{\n        $installPath = $env:msdeployinstallpath\n\n        if(!$installPath){\n            $keysToCheck = @('hklm:\\SOFTWARE\\Microsoft\\IIS Extensions\\MSDeploy\\3','hklm:\\SOFTWARE\\Microsoft\\IIS Extensions\\MSDeploy\\2','hklm:\\SOFTWARE\\Microsoft\\IIS Extensions\\MSDeploy\\1')\n\n            foreach($keyToCheck in $keysToCheck){\n                if(Test-Path $keyToCheck){\n                    $installPath = (Get-itemproperty $keyToCheck -Name InstallPath -ErrorAction SilentlyContinue | select -ExpandProperty InstallPath -ErrorAction SilentlyContinue)\n                }\n\n                if($installPath){\n                    break;\n                }\n            }\n        }\n\n        if(!$installPath){\n            throw \"Unable to find msdeploy.exe, please install it and try again\"\n        }\n\n        [string]$msdInstallLoc = (join-path $installPath 'msdeploy.exe')\n\n        \"Found msdeploy.exe at [{0}]\" -f $msdInstallLoc | Write-Verbose\n        \n        $msdInstallLoc\n    }\n}\n\nfunction InternalNormalize-MSDeployUrl{\n    [cmdletbinding()]\n    param(\n        [Parameter(Position=0,Mandatory=$true)]\n        [string]$serviceUrl,\n\n        [string] $siteName,\n        \n        [ValidateSet('WMSVC','RemoteAgent','InProc')]\n        [string]$serviceMethod = 'WMSVC'\n    )\n    process{\n        $tempUrl = $serviceUrl\n        $resultUrl = $serviceUrl\n\n        $httpsStr = 'https://'\n        $httpStr = 'http://'\n        $msdeployAxd = 'msdeploy.axd'\n\n        if(-not [string]::IsNullOrWhiteSpace($serviceUrl)){\n            if([string]::Compare($serviceMethod,'WMSVC',[StringComparison]::OrdinalIgnoreCase) -eq 0){\n                # if no http or https then add one\n                if(-not ($serviceUrl.StartsWith($httpStr,[StringComparison]::OrdinalIgnoreCase) -or \n                            $serviceUrl.StartsWith($httpsStr,[StringComparison]::OrdinalIgnoreCase)) ){\n\n                    $serviceUrl = [string]::Concat($httpsStr,$serviceUrl.TrimStart())\n                }\n                [System.Uri]$serviceUri = New-Object -TypeName 'System.Uri' $serviceUrl\n                [System.UriBuilder]$serviceUriBuilder = New-Object -TypeName 'System.UriBuilder' $serviceUrl\n\n                # if it's https and the port was not passed in override it to 8172\n                if( ([string]::Compare('https',$serviceUriBuilder.Scheme,[StringComparison]::OrdinalIgnoreCase) -eq 0) -and\n                     -not $serviceUrl.Contains((':{0}' -f $serviceUriBuilder.Port)) ) {\n                    $serviceUriBuilder.Port = 8172\n                }\n\n                # if no path then add one\n                if([string]::Compare('/',$serviceUriBuilder.Path,[StringComparison]::OrdinalIgnoreCase) -eq 0){\n                    $serviceUriBuilder.Path = $msdeployAxd\n                }\n                \n                if ([string]::IsNullOrEmpty($serviceUriBuilder.Query) -and -not([string]::IsNullOrEmpty($siteName)))\n                {\n                    $serviceUriBuilder.Query = \"site=\" + $siteName;\n                }\n\n                $resultUrl = $serviceUriBuilder.Uri.AbsoluteUri\n            }\n            elseif([string]::Compare($serviceMethod,'RemoteAgent',[StringComparison]::OrdinalIgnoreCase) -eq 0){\n                [System.UriBuilder]$serviceUriBuilder = New-Object -TypeName 'System.UriBuilder' $serviceUrl\n                # http://{computername}/MSDEPLOYAGENTSERVICE\n                # remote agent must use http\n                $serviceUriBuilder.Scheme = 'http'\n                $serviceUriBuilder.Path = '/MSDEPLOYAGENTSERVICE'\n                \n                $resultUrl = $serviceUriBuilder.Uri.AbsoluteUri\n            }\n            else{\n                # see if it's for localhost\n                [System.Uri]$serviceUri = New-Object -TypeName 'System.Uri' $serviceUrl\n                $resultUrl = $serviceUri.AbsoluteUri\n            }\n        }\n\n        # return the result to the caller\n        $resultUrl        \n    }\n}\n\nfunction InternalRegister-AspNetKnownPublishHandlers{\n    [cmdletbinding()]\n    param()\n    process{\n        'Registering MSDeploy handler' | Write-Verbose\n        Register-AspnetPublishHandler -name 'MSDeploy' -force -handler {\n            [cmdletbinding()]\n            param(\n                [Parameter(Mandatory = $true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]\n                $publishProperties,\n                [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)]\n                $packOutput\n            )\n\n            Publish-AspNetMSDeploy -publishProperties $publishProperties -packOutput $packOutput\n        }\n\n        'Registering MSDeploy package handler' | Write-Verbose\n        Register-AspnetPublishHandler -name 'Package' -force -handler {\n            [cmdletbinding()]\n            param(\n                [Parameter(Mandatory = $true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]\n                $publishProperties,\n                [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)]\n                $packOutput\n            )\n\n            Publish-AspNetMSDeployPackage -publishProperties $publishProperties -packOutput $packOutput\n        }\n\n        'Registering FileSystem handler' | Write-Verbose\n        Register-AspnetPublishHandler -name 'FileSystem' -force -handler {\n            [cmdletbinding()]\n            param(\n                [Parameter(Mandatory = $true,Position=0,ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true)]\n                $publishProperties,\n                [Parameter(Mandatory = $true,Position=1,ValueFromPipelineByPropertyName=$true)]\n                $packOutput\n            )\n    \n            Publish-AspNetFileSystem -publishProperties $publishProperties -packOutput $packOutput\n        }\n    }\n}\n\n<#\n.SYNOPSIS\n    Used for testing purposes only.\n#>\nfunction InternalReset-AspNetPublishHandlers{\n    [cmdletbinding()]\n    param()\n    process{\n        $script:AspNetPublishHandlers = @{}\n        InternalRegister-AspNetKnownPublishHandlers\n    }\n}\n\nExport-ModuleMember -function Get-*,Publish-*,Register-*,Enable-*\nif($env:IsDeveloperMachine){\n    # you can set the env var to expose all functions to importer. easy for development.\n    # this is required for executing pester test cases, it's set by build.ps1\n    Export-ModuleMember -function *\n}\n\n# register the handlers so that Publish-AspNet can be called\nInternalRegister-AspNetKnownPublishHandlers\n\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Properties/launchSettings.json",
    "content": "{\n  \"iisSettings\": {\n    \"windowsAuthentication\": false,\n    \"anonymousAuthentication\": true,\n    \"iisExpress\": {\n      \"applicationUrl\": \"http://localhost:9385/\",\n      \"sslPort\": 0\n    }\n  },\n  \"profiles\": {\n    \"IIS Express\": {\n      \"commandName\": \"IISExpress\",\n      \"launchBrowser\": true,\n      \"launchUrl\": \"api/values\",\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Production\"\n      }\n    },\n    \"ACEWebService\": {\n      \"commandName\": \"Project\",\n      \"environmentVariables\": {\n        \"ASPNETCORE_ENVIRONMENT\": \"Production\"\n      },\n      \"applicationUrl\": \"http://localhost:5000\"\n    }\n  }\n}"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Security/ApiKeyPolicy.cs",
    "content": "﻿using ACEWebService.Entities;\nusing ACEWebService.Security;\nusing Microsoft.AspNetCore.Authorization;\nusing Microsoft.Extensions.Primitives;\nusing System.Linq;\nusing System.Threading.Tasks;\n\nnamespace ACEWebService.Security\n{\n    public class ApiKeyRequirement : IAuthorizationRequirement\n    {\n        public ApiKeyRequirement()\n        {\n\n        }\n    }\n\n    public class ApiKeyHandler : AuthorizationHandler<ApiKeyRequirement>\n    {\n        private ACEWebServiceDbContext _context;\n\n        public ApiKeyHandler(ACEWebServiceDbContext context)\n        {\n            _context = context;\n        }\n\n        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, ApiKeyRequirement requirement)\n        {\n            var mvcContext = context.Resource as Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext;\n\n            if (mvcContext != null)\n            {\n                StringValues apiKeyHeaderValues = new StringValues();\n                mvcContext.HttpContext.Request.Headers.TryGetValue(\"x-apikey\", out apiKeyHeaderValues);\n\n                User user = _context.Users.SingleOrDefault(u => u.ApiKey == apiKeyHeaderValues.ToString());\n                if (user.ApiKey == apiKeyHeaderValues.ToString())\n                {\n                    context.Succeed(requirement);\n                }\n            }\n            return Task.CompletedTask;\n        }\n    }\n}"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Security/IsAdminPolicy.cs",
    "content": "﻿using ACEWebService.Entities;\nusing Microsoft.AspNetCore.Authorization;\nusing Microsoft.Extensions.Primitives;\nusing System.Linq;\nusing System.Threading.Tasks;\n\nnamespace ACEWebService.Security\n{\n    public class IsAdminRequirement : IAuthorizationRequirement\n    {\n        public IsAdminRequirement()\n        {\n\n        }\n    }\n\n    public class IsAdminHandler : AuthorizationHandler<ApiKeyRequirement>\n    {\n        private ACEWebServiceDbContext _context;\n\n        public IsAdminHandler(ACEWebServiceDbContext context)\n        {\n            _context = context;\n        }\n\n        protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, ApiKeyRequirement requirement)\n        {\n            var mvcContext = context.Resource as Microsoft.AspNetCore.Mvc.Filters.AuthorizationFilterContext;\n\n            if (mvcContext != null)\n            {\n                StringValues apiKeyHeaderValues = new StringValues();\n                mvcContext.HttpContext.Request.Headers.TryGetValue(\"x-apikey\", out apiKeyHeaderValues);\n\n                User user = _context.Users.SingleOrDefault(u => u.ApiKey == apiKeyHeaderValues.ToString());\n                if (user.ApiKey == apiKeyHeaderValues.ToString())\n                {\n                    if (user.IsAdmin)\n                    {\n                        context.Succeed(requirement);\n                    }\n                }\n            }\n            return Task.CompletedTask;\n        }\n    }\n}"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Services/IAceConfiguration.cs",
    "content": "﻿using Microsoft.Extensions.Configuration;\n\nnamespace ACEWebService.Services\n{\n    public interface IAceConfiguration\n    {\n\n    }\n\n    public class AceConfiguration : IAceConfiguration\n    {\n        private IConfigurationRoot _configuration;\n\n        public AceConfiguration(IConfigurationRoot configuration)\n        {\n            _configuration = configuration;\n        }\n    }\n}"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Services/ICryptographyService.cs",
    "content": "﻿using Microsoft.AspNetCore.DataProtection;\n\nnamespace ACEWebService.Services\n{\n    public interface ICryptographyService\n    {\n        string Encrypt(string clearText);\n        string Decrypt(string cipherText);\n    }\n\n    public class AESCryptographyService : ICryptographyService\n    {\n        private readonly IDataProtector _protector;\n\n        public AESCryptographyService(IDataProtectionProvider provider)\n        {\n            _protector = provider.CreateProtector(GetType().FullName);\n        }\n\n        public string Encrypt(string plaintext)\n        {\n            return _protector.Protect(plaintext);\n        }\n\n        public string Decrypt(string encryptedText)\n        {\n            return _protector.Unprotect(encryptedText);\n        }\n    }\n}"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Services/IDiscoveryService.cs",
    "content": "﻿using ACEWebService.Entities;\nusing ACEWebService.ViewModels;\nusing System;\nusing System.Collections.Generic;\n//using System.DirectoryServices;\nusing System.Net.Sockets;\nusing System.Linq;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Extensions.Configuration;\nusing System.Collections.Concurrent;\n\nnamespace ACEWebService.Services\n{\n    public interface IDiscoveryService\n    {\n        //void Discover(DiscoveryActiveDirectoryViewModel param);\n        void Discover(DiscoveryComputerListViewModel param);\n    }\n\n    public class DiscoveryActiveDirectoryService : IDiscoveryService\n    {\n        private ACEWebServiceDbContext _context;\n        IConfigurationRoot _configuration;\n        ICryptographyService _cryptoService;\n\n        public DiscoveryActiveDirectoryService(ACEWebServiceDbContext context, ICryptographyService cryptoService)\n        {\n            _context = context;\n            _cryptoService = cryptoService;\n        }\n\n        /*\n        public void Discover(DiscoveryActiveDirectoryViewModel param)\n        {\n            Console.WriteLine(\"=========================\");\n            Console.WriteLine(\"Domain: {0}\", param.Domain);\n            Console.WriteLine(\"=========================\");\n\n            List<Computer> computerList = new List<Computer>();\n\n            Console.WriteLine(\"=========================\");\n            Console.WriteLine(\"CredentialId: {0}\", param.CredentialId);\n            Console.WriteLine(\"=========================\");\n\n            Credential credential = _context.Credentials.SingleOrDefault(cred => cred.Id == param.CredentialId);\n\n            Console.WriteLine(\"=========================\");\n            Console.WriteLine(\"UserName: {0}\", credential.UserName);\n            Console.WriteLine(\"=========================\");\n\n            SearchResultCollection results = GetDomainComputers(param.Domain, credential);\n\n            foreach (SearchResult result in results)\n            {\n                string computername = (string)result.Properties[\"dnshostname\"][0];\n                //string operatingsystem = (string)result.Properties[\"operatingsystem\"][0];\n\n                Console.WriteLine(\"=========================\");\n                Console.WriteLine(\"ComputerName: {0}\", computername);\n                Console.WriteLine(\"=========================\");\n\n                try\n                {\n                    Computer computer = _context.Computers.Single(c => c.ComputerName == computername);\n\n                    computer.ComputerName = computername;\n                    //computer.OperatingSystem = operatingsystem;\n                    computer.CredentialId = param.CredentialId;\n                    computer.SSH = TestPort(computername, 22);\n                    computer.RPC = TestPort(computername, 135);\n                    computer.SMB = TestPort(computername, 445);\n                    computer.WinRM = TestPort(computername, 5985);\n\n                    _context.Computers.Update(computer);\n                }\n                catch\n                {\n                    Guid id = Guid.NewGuid();\n                    Console.WriteLine(\"=========================\");\n                    Console.WriteLine(\"Id: {0}\", id);\n                    Console.WriteLine(\"=========================\");\n\n                    computerList.Add(new Computer\n                    {\n                        Id = id,\n                        ComputerName = computername,\n                        OperatingSystem = null,\n                        CredentialId = param.CredentialId,\n                        Scanned = false,\n                        SSH = TestPort(computername, 22),\n                        RPC = TestPort(computername, 135),\n                        SMB = TestPort(computername, 445),\n                        WinRM = TestPort(computername, 5985)\n                    });\n                }\n            }\n\n            _context.Computers.AddRange(computerList);\n            _context.SaveChanges();\n        }\n        */\n\n        /*\n        public void Discover(DiscoveryComputerListViewModel param)\n        {\n            List<Computer> computerList = new List<Computer>();\n\n            foreach(string name in param.ComputerName)\n            {\n                Console.WriteLine(\"=========================\");\n                Console.WriteLine(\"ComputerName: {0}\", name);\n                Console.WriteLine(\"=========================\");\n\n                try\n                {\n                    Computer computer = _context.Computers.Single(c => c.ComputerName == name);\n\n                    computer.SSH = TestPort(computer.ComputerName, 22);\n                    computer.RPC = TestPort(computer.ComputerName, 135);\n                    computer.SMB = TestPort(computer.ComputerName, 445);\n                    computer.WinRM = TestPort(computer.ComputerName, 5985);\n\n                    _context.Computers.Update(computer);\n                }\n                catch\n                {\n                    Guid id = Guid.NewGuid();\n                    Console.WriteLine(\"=========================\");\n                    Console.WriteLine(\"Id: {0}\", id);\n                    Console.WriteLine(\"=========================\");\n\n                    computerList.Add(new Computer\n                    {\n                        Id = id,\n                        ComputerName = name,\n                        OperatingSystem = null,\n                        CredentialId = param.CredentialId,\n                        Scanned = false,\n                        SSH = TestPort(name, 22),\n                        RPC = TestPort(name, 135),\n                        SMB = TestPort(name, 445),\n                        WinRM = TestPort(name, 5985)\n                    });\n\n                    //computerList.Add(GetComputer(name, null, param.CredentialId, false));\n                }\n            }\n\n            Console.WriteLine(\"=========================\");\n            Console.WriteLine(\"Post Loop\");\n            Console.WriteLine(\"=========================\");\n\n            _context.Computers.AddRange(computerList);\n            _context.SaveChanges();\n        }\n        */\n\n        public void Discover(DiscoveryComputerListViewModel param)\n        {\n            var computerDictionary = new ConcurrentDictionary<string, Computer>();\n            // Add all current DB entries to computerDictionary\n            foreach (Computer comp in _context.Computers)\n            {\n                computerDictionary.TryAdd(comp.ComputerName, comp);\n            }\n\n            // Set up Threads\n            var numThreads = 20;\n            var collection = new BlockingCollection<Wrapper<ACEComputer>>();\n            var tasks = new Task[numThreads];\n            \n            for (var x = 0; x < numThreads; x++)\n            {\n                tasks[x] = CreateTask(collection, computerDictionary);\n            }\n\n            foreach (string computer in param.ComputerName)\n            {\n                collection.Add(new Wrapper<ACEComputer>\n                {\n                    Item = new ACEComputer{\n                        ComputerName = computer,\n                        CredentialId = param.CredentialId\n                    }\n                });\n            }\n            collection.CompleteAdding();\n            Console.WriteLine(\"Finished adding items to queue, waiting on tasks\");\n            Task.WaitAll(tasks);\n\n            // Delete all old entries from the Computer Table\n            _context.Computers.RemoveRange(_context.Computers);\n            _context.SaveChanges();\n            // Update table with all entries from the cache\n            _context.Computers.AddRange(computerDictionary.Values);\n            // Save all changes done to the DB\n            _context.SaveChanges();\n        }\n\n        private static Task CreateTask(BlockingCollection<Wrapper<ACEComputer>> input, ConcurrentDictionary<string, Computer> dictionary)\n        {\n            return Task.Factory.StartNew(() =>\n            {\n                foreach (var x in input.GetConsumingEnumerable())\n                {\n                    Computer oldcomp = new Computer();\n                    if (dictionary.TryGetValue(x.Item.ComputerName, out oldcomp))\n                    {\n                        dictionary.TryUpdate(\n                            x.Item.ComputerName,\n                            new Computer\n                            {\n                                Id = oldcomp.Id,\n                                ComputerName = x.Item.ComputerName,\n                                OperatingSystem = null,\n                                CredentialId = x.Item.CredentialId,\n                                Scanned = oldcomp.Scanned,\n                                SSH = TestPort(x.Item.ComputerName, 22),\n                                RPC = TestPort(x.Item.ComputerName, 135),\n                                SMB = TestPort(x.Item.ComputerName, 445),\n                                WinRM = TestPort(x.Item.ComputerName, 5985)\n                            }, \n                            oldcomp);\n                    }\n                    else\n                    {\n                        dictionary.TryAdd(x.Item.ComputerName, new Computer\n                        {\n                            Id = Guid.NewGuid(),\n                            ComputerName = x.Item.ComputerName,\n                            OperatingSystem = null,\n                            CredentialId = x.Item.CredentialId,\n                            Scanned = false,\n                            SSH = TestPort(x.Item.ComputerName, 22),\n                            RPC = TestPort(x.Item.ComputerName, 135),\n                            SMB = TestPort(x.Item.ComputerName, 445),\n                            WinRM = TestPort(x.Item.ComputerName, 5985)\n                        });\n                    }\n\n                    x.Item = null;\n                }\n                Console.WriteLine($\"Exiting thread {Thread.CurrentThread}\");\n            },\n            //Use this to make sure each task gets its own thread\n            TaskCreationOptions.LongRunning);\n        }\n\n        private Computer GetComputer(string computername, string operatingsystem, Guid credentialId, bool scanned)\n        {\n            return new Computer\n            {\n                Id = Guid.NewGuid(),\n                ComputerName = computername,\n                OperatingSystem = operatingsystem,\n                CredentialId = credentialId,\n                Scanned = scanned,\n                SSH = TestPort(computername, 22),\n                RPC = TestPort(computername, 135),\n                SMB = TestPort(computername, 445),\n                WinRM = TestPort(computername, 5985)\n            };\n        }\n\n        internal static bool TestPort(string hostname, int port)\n        {\n            try\n            {\n                using (var client = new TcpClient())\n                {\n                    var result = client.BeginConnect(hostname, port, null, null);\n                    var success = result.AsyncWaitHandle.WaitOne(200);\n                    if (!success)\n                    {\n                        return false;\n                    }\n\n                    client.EndConnect(result);\n                }\n            }\n            catch\n            {\n                return false;\n            }\n            return true;\n        }\n    }\n\n    internal class ACEComputer\n    {\n        public string ComputerName;\n        public Guid CredentialId;\n    }\n}"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Services/IDownloadService.cs",
    "content": "﻿using ACEWebService.Entities;\nusing ACEWebService.ViewModels;\nusing Microsoft.Extensions.Options;\nusing Microsoft.Management.Infrastructure;\nusing Microsoft.Management.Infrastructure.Options;\nusing System;\nusing System.Linq;\nusing System.Security;\nusing System.Text;\n\nnamespace ACEWebService.Services\n{\n    public interface IDownloadService\n    {\n        void DownloadRequest(DownloadRequestViewModel param, Guid Id);\n    }\n\n    public class DownloadService : IDownloadService\n    {\n        private ACEWebServiceDbContext _context;\n        ICryptographyService _cryptoService;\n        private readonly AppSettings _settings;\n\n        public DownloadService(ACEWebServiceDbContext context, ICryptographyService cryptoService, IOptions<AppSettings> settings)\n        {\n            _context = context;\n            _cryptoService = cryptoService;\n            _settings = settings.Value;\n        }\n\n        public void DownloadRequest(DownloadRequestViewModel param, Guid Id)\n        {\n            Computer computer = _context.Computers.Single(c => c.Id == param.ComputerId);\n            Credential credential = _context.Credentials.Single(c => c.Id == computer.CredentialId);\n\n            if (computer.WinRM || computer.RPC)\n            {\n                // Create a PowerShell script to run PSInvestigate\n                string executionArgs = string.Format(\n                    @\"Download-AceFile -Uri {0} -Thumbprint {1} -Path {2} -Id {3}\",\n                    param.Uri,\n                    _settings.Thumbprint,\n                    param.FilePath,\n                    Id\n                );\n                string psScript = string.Format(\n                    @\"Invoke-Expression (New-Object System.Net.WebClient).DownloadString('{0}/scripts/Download-AceFile.ps1'); {1}; Get-Process | Out-File -FilePath C:\\temp\\jared.txt\",\n                    param.Uri,\n                    executionArgs\n                );\n                Console.WriteLine(\"[{0}] PsScript: {1}\", computer.ComputerName, psScript);\n                string commandline = string.Format(\n                    @\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -EncodedCommand {0}\",\n                    Convert.ToBase64String(Encoding.Unicode.GetBytes(psScript))\n                );\n\n                if (computer.WinRM)\n                {\n                    KickOffCim(computer, credential, commandline, new WSManSessionOptions());\n                }\n                else\n                {\n                    KickOffCim(computer, credential, commandline, new DComSessionOptions());\n                }\n            }\n            else if (computer.SSH)\n            {\n                throw new NotImplementedException();\n            }\n            else if (computer.SMB)\n            {\n                throw new NotImplementedException();\n            }\n            else\n            {\n                throw new Exception(string.Format(\"No valid protocols available for {0}\", computer.ComputerName));\n            }\n        }\n\n        private void KickOffCim(Computer computer, Credential credential, string commandline, CimSessionOptions options)\n        {\n            // Convert stored password to a secure string\n            SecureString securePwd = new SecureString();\n            foreach (char c in _cryptoService.Decrypt(credential.Password))\n            {\n                Console.WriteLine(\"[char]: {0}\", c);\n                securePwd.AppendChar(c);\n            }\n            \n            CimCredential cimCreds = null;\n\n            if (credential.UserName.Contains('\\\\'))\n            {\n                // Create a CimCredential object\n                cimCreds = new CimCredential(PasswordAuthenticationMechanism.Kerberos, credential.UserName.Split('\\\\')[0], credential.UserName.Split('\\\\')[1], securePwd);\n            }\n            else\n            {\n                // Create a CimCredential object\n                cimCreds = new CimCredential(PasswordAuthenticationMechanism.Default, null, credential.UserName, securePwd);\n            }\n\n            // Create a CimSession with the remote system\n            options.AddDestinationCredentials(cimCreds);\n            CimSession session = CimSession.Create(computer.ComputerName, options);\n\n            // Create a CimMethodParametersCollection to pass to method invocation\n            CimMethodParametersCollection collection = new CimMethodParametersCollection\n            {\n                CimMethodParameter.Create(\"CommandLine\", commandline, CimFlags.None)\n            };\n\n            CimMethodResult result = session.InvokeMethod(\"root/cimv2\", \"Win32_Process\", \"Create\", collection);\n            if (result.ReturnValue.ToString() == \"0\")\n            {\n\n            }\n            else\n            {\n\n            }\n\n            session.Dispose();\n        }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Services/ISweepExecutionService.cs",
    "content": "﻿using ACEWebService.Entities;\nusing ACEWebService.ViewModels;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.Management.Infrastructure;\nusing Microsoft.Management.Infrastructure.Options;\nusing Renci.SshNet;\nusing Microsoft.Extensions.Configuration;\nusing System;\nusing System.Collections.Concurrent;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Security;\nusing System.Text;\nusing System.Threading;\nusing System.Threading.Tasks;\nusing Microsoft.Extensions.Options;\n\nnamespace ACEWebService.Services\n{\n    public interface ISweepExecutionService\n    {\n        Guid Sweep(SweepExecutionViewModel param);\n    }\n\n    public class SweepExecutionService : ISweepExecutionService\n    {\n        private ACEWebServiceDbContext _context;\n        private ICryptographyService _cryptoService;\n        private readonly AppSettings _settings;\n\n        public SweepExecutionService(ACEWebServiceDbContext context, ICryptographyService cryptoService, IOptions<AppSettings> settings)\n        {\n            _context = context;\n            _cryptoService = cryptoService;\n            _settings = settings.Value;\n        }\n\n        public Guid Sweep(SweepExecutionViewModel param)\n        {\n            // Generate Sweep Id and add the Sweep to the DB\n            Guid Id = Guid.NewGuid();\n            _context.Sweeps.Add(new Sweep\n            {\n                Id = Id,\n                Status = \"Running\",\n                StartTime = DateTime.UtcNow,\n                ScanCount = param.ComputerId.Length,\n                CompleteCount = 0\n            });\n            _context.SaveChanges();\n\n            // Retrieve the target Script's data from the DB\n            Script script = _context.Scripts.Single(s => s.Id == param.ScriptId);\n            \n            // Retrieve Credential objects from the DB and put in a dictionary based on the Id field\n            Dictionary<Guid, Credential> credDictionary = _context.Credentials.ToDictionary(credential => credential.Id);\n\n            // Create Parallel Tasks\n            int numThreads = 20;\n            var collection = new BlockingCollection<Wrapper<ACETasking>>(1000);\n            var tasks = new Task[numThreads];\n            for (var x = 0; x < numThreads; x++)\n            {\n                tasks[x] = CreateTask(collection);\n            }\n\n            foreach (Guid compid in param.ComputerId)\n            {\n                // Generate Scan Id and add the Scan to the DB\n                Guid scanId = Guid.NewGuid();\n                _context.Scans.Add(new Scan\n                {\n                    Id = scanId,\n                    Status = \"Running\",\n                    StartTime = DateTime.UtcNow,\n                    ComputerId = compid,\n                    SweepIdentifier = Id\n                });\n                \n                // Retreive Computer objects from DB\n                Computer computer = _context.Computers.Single(c => c.Id == compid);\n\n                // Add items to the task collection\n                collection.Add(new Wrapper<ACETasking>\n                {\n                    Item = new ACETasking{\n                        Computer = computer,\n                        CredentialDictionary = credDictionary,\n                        Uri = param.ExternalUri,\n                        Thumbprint = _settings.Thumbprint,\n                        Script = script,\n                        SweepId = Id,\n                        ScanId = scanId\n                    }\n                });\n            }\n\n            _context.SaveChanges();\n            collection.CompleteAdding();\n            Console.WriteLine(\"Finished adding items to queue, waiting on tasks\");\n            Task.WaitAll(tasks);\n\n            return Id;\n        }\n\n        // I need to change the type of object expected by Wrapper to something more complex\n        private Task CreateTask(BlockingCollection<Wrapper<ACETasking>> input)\n        {\n            return Task.Factory.StartNew(() =>\n            {\n                foreach (var x in input.GetConsumingEnumerable())\n                {\n                    Credential credential = x.Item.CredentialDictionary[x.Item.Computer.CredentialId];\n                    \n                    if (x.Item.Computer.WinRM || x.Item.Computer.RPC)\n                    {\n                        // Create a PowerShell script to run PSInvestigate\n                        string executionArgs = string.Format(\n                            @\"Start-AceScript -ServerUri {0} -ScriptUri {1} -Thumbprint {2} -SweepId {3} -ScanId {4} -RoutingKey {5}\",\n                            x.Item.Uri,\n                            x.Item.Script.Uri,\n                            x.Item.Thumbprint,\n                            x.Item.SweepId,\n                            x.Item.ScanId,\n                            x.Item.Script.RoutingKey\n                        );\n\n                        string psScript = string.Format(\n                            @\"[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {{$certificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]$args[1]; if($certificate -eq $null){{return $true}}; if($certificate.Thumbprint -eq '{0}'){{return $true}}else{{return $false}}}}; Invoke-Expression (New-Object System.Net.WebClient).DownloadString('{1}/scripts/Start-AceScript.ps1'); {2}\", \n                            x.Item.Thumbprint,\n                            x.Item.Uri, \n                            executionArgs\n                        );\n\n                        Console.WriteLine(\"[WinRM:{0}] PsScript: {1}\", x.Item.Computer.ComputerName, psScript);\n\n                        string commandline = string.Format(\n                            @\"C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe -EncodedCommand {0}\", \n                            Convert.ToBase64String(Encoding.Unicode.GetBytes(psScript))\n                        );\n\n                        if (x.Item.Computer.WinRM)\n                        {\n                            KickOffCimAsync(x.Item.Computer, credential, commandline, new WSManSessionOptions());\n                        }\n                        else\n                        {\n                            KickOffCimAsync(x.Item.Computer, credential, commandline, new DComSessionOptions());\n                        }\n                    }\n                    else if (x.Item.Computer.SSH)\n                    {\n                        //Creates a string of the target script to run over SSH\n                        string rawScript = System.Text.Encoding.ASCII.GetString(System.IO.File.ReadAllBytes(string.Format(\"scripts\\\\{0}.ace\", x.Item.Script.Id)));\n\n                        // Build command line to be run over SSH\n                        string commandline = string.Format(\n                            @\"echo \"\"{0}\"\" | sudo python - --Server {1} --SweepId {2} --ScanId {3} --RoutingKey {4} --Thumbprint {5}\",\n                            rawScript,\n                            x.Item.Uri, \n                            x.Item.SweepId,\n                            x.Item.ScanId,\n                            x.Item.Script.RoutingKey,\n                            x.Item.Thumbprint\n                        );\n                        Console.WriteLine(\"[SSH] CommandLine: {0}\", commandline);\n\n                        KickOffSSHAsync(x.Item.Computer, credential, commandline);\n                    }\n                    else if (x.Item.Computer.SMB)\n                    {\n                        throw new NotImplementedException();\n                    }\n                    else\n                    {\n                        throw new Exception(string.Format(\"No valid protocols available for {0}\", x.Item.Computer.ComputerName));\n                    }\n\n                    x.Item = null;\n                }\n            },\n\n            //Use this to make sure each task gets its own thread\n            TaskCreationOptions.LongRunning);\n        }\n\n        private void KickOffCimAsync(Computer computer, Credential credential, string commandline, CimSessionOptions options)\n        {\n            // Convert stored password to a secure string\n            SecureString securePwd = new SecureString();\n            foreach (char c in _cryptoService.Decrypt(credential.Password))\n            {\n                securePwd.AppendChar(c);\n            }\n\n            CimCredential cimCreds = null;\n\n            if (credential.UserName.Contains('\\\\'))\n            {\n                // Create a CimCredential object\n                cimCreds = new CimCredential(PasswordAuthenticationMechanism.Kerberos, credential.UserName.Split('\\\\')[0], credential.UserName.Split('\\\\')[1], securePwd);\n            }\n            else\n            {\n                // Create a CimCredential object\n                cimCreds = new CimCredential(PasswordAuthenticationMechanism.Default, null, credential.UserName, securePwd);\n            }\n\n            // Create a CimSession with the remote system\n            options.AddDestinationCredentials(cimCreds);\n            CimSession session = CimSession.Create(computer.ComputerName, options);\n\n            // Create a CimMethodParametersCollection to pass to method invocation\n            CimMethodParametersCollection collection = new CimMethodParametersCollection();\n            collection.Add(CimMethodParameter.Create(\"CommandLine\", commandline, CimFlags.None));\n\n            CimMethodResult result = session.InvokeMethod(\"root/cimv2\", \"Win32_Process\", \"Create\", collection);\n            if (result.ReturnValue.ToString() == \"0\")\n            {\n\n            }\n            else\n            {\n\n            }\n\n            session.Dispose();\n        }\n\n        private void KickOffSSHAsync(Computer computer, Credential credential, string commandline)\n        {\n            using (var client = new SshClient(computer.ComputerName, credential.UserName, _cryptoService.Decrypt(credential.Password)))\n            {\n                client.Connect();\n                client.RunCommand(commandline);\n                client.Disconnect();\n            }\n        }\n    }\n\n    internal class Wrapper<T>\n    {\n        public T Item { get; set; }\n    }\n\n    internal class ACETasking\n    {\n        public Computer Computer;\n        public Dictionary<Guid, Credential> CredentialDictionary;\n        public string Uri;\n        public string Thumbprint;\n        public Script Script;\n        public Guid SweepId;\n        public Guid ScanId;\n    }\n}"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Services/ISweepResultProcessorService.cs",
    "content": "﻿using ACEWebService.ViewModels;\nusing Microsoft.Extensions.Options;\nusing RabbitMQ.Client;\nusing System;\nusing System.IO;\nusing System.Text;\n\nnamespace ACEWebService.Services\n{\n    public interface ISweepResultProcessorService\n    {\n        void Process(Guid scanId, SweepResultViewModel scanData);\n    }\n\n    public class ScanResultRabbitMQService : ISweepResultProcessorService\n    {\n        private readonly AppSettings _settings;\n\n        public ScanResultRabbitMQService(IOptions<AppSettings> settings)\n        {\n            _settings = settings.Value;\n        }\n\n        public void Process(Guid scanId, SweepResultViewModel sweepData)\n        {\n            var factory = new ConnectionFactory()\n            {\n                HostName = _settings.RabbitMQServer,\n                UserName = _settings.RabbitMQUserName,\n                Password = _settings.RabbitMQPassword,\n            };\n\n            using (var connection = factory.CreateConnection())\n            using (var channel = connection.CreateModel())\n            {\n                channel.ExchangeDeclare(exchange: \"ace_exchange\", type: \"topic\", durable: true);\n\n                foreach (string message in sweepData.Data)\n                {\n                    byte[] body = Encoding.UTF8.GetBytes(message);\n                    string key = sweepData.RoutingKey;\n\n                    if(key.Contains(\"none\"))\n                    {\n                        key = key.Replace(\"none.\", \"\");\n                    }\n\n                    channel.BasicPublish(exchange: \"ace_exchange\",\n                        routingKey: key,\n                        basicProperties: null,\n                        body: body);\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Startup.cs",
    "content": "﻿using ACEWebService.Services;\nusing ACEWebService.Entities;\nusing ACEWebService.Security;\nusing Microsoft.AspNetCore.Builder;\nusing Microsoft.AspNetCore.DataProtection;\nusing Microsoft.AspNetCore.Diagnostics;\nusing Microsoft.AspNetCore.Hosting;\nusing Microsoft.AspNetCore.Http;\nusing Microsoft.AspNetCore.Mvc.Versioning;\nusing Microsoft.AspNetCore.StaticFiles;\nusing Microsoft.Extensions.Configuration;\nusing Microsoft.Extensions.DependencyInjection;\nusing Microsoft.Extensions.FileProviders;\nusing Microsoft.Extensions.Logging;\nusing System;\nusing System.IO;\nusing System.Text;\nusing VTIProxy.ViewModels;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.AspNetCore.Authorization;\nusing Microsoft.AspNetCore.Mvc.Authorization;\nusing System;\n\nnamespace ACEWebService\n{\n    public class Startup\n    {\n        private IHostingEnvironment _currentEnvironment { get; set; }\n\n        public Startup(IHostingEnvironment env)\n        {\n            _currentEnvironment = env;\n\n            var builder = new ConfigurationBuilder()\n                .SetBasePath(env.ContentRootPath)\n                .AddJsonFile(\"appsettings.json\", optional: true, reloadOnChange: true)\n                .AddJsonFile($\"appsettings.{env.EnvironmentName}.json\", optional: true);\n\n            builder.AddEnvironmentVariables();\n            Configuration = builder.Build();\n        }\n\n        public IConfigurationRoot Configuration { get; }\n\n        // This method gets called by the runtime. Use this method to add services to the container.\n        public void ConfigureServices(IServiceCollection services)\n        {\n            // Add framework services.\n            services.AddMvc();\n\n            services.AddDbContext<ACEWebServiceDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString(\"DefaultConnection\")));\n\n            services.Configure<AppSettings>(Configuration.GetSection(\"AppSettings\"));\n\n            services.AddAuthorization(\n                options =>\n                {\n                    options.AddPolicy(\"ApiKey\", policy => policy.Requirements.Add(new ApiKeyRequirement()));\n                }\n            );\n\n            services.AddSingleton<IAuthorizationHandler, ApiKeyHandler>();\n\n            services.AddScoped<IAceConfiguration, AceConfiguration>(\n                provider =>\n                {\n                    return new AceConfiguration(Configuration);\n                }\n            );\n\n            services.AddScoped<ICryptographyService, AESCryptographyService>(\n                provider =>\n                {\n                    var serviceCollection = new ServiceCollection();\n                    serviceCollection.AddDataProtection();\n                    var serviceProvider = serviceCollection.BuildServiceProvider();\n                    return ActivatorUtilities.CreateInstance<AESCryptographyService>(serviceProvider);\n                }\n            );\n\n            services.AddScoped<IDiscoveryService, DiscoveryActiveDirectoryService>();\n\n            services.AddScoped<IDownloadService, DownloadService>();\n            \n            /*\n            services.AddScoped<ISweepResultProcessorService, SweepResultFileWriterService>(\n                provider =>\n                {\n                    return new SweepResultFileWriterService(@\"C:\\test\\scans\");\n                }\n            );\n            */\n\n            services.AddScoped<ISweepResultProcessorService, ScanResultRabbitMQService>();\n\n            services.AddScoped<ISweepExecutionService, SweepExecutionService>();\n\n            /*\n            services.AddScoped<ISchedulingService, SchedulingQuartzService>(\n                provider =>\n                {\n                    return new SchedulingQuartzService();\n                }\n            );\n            */\n\n            services.AddApiVersioning(\n                o =>\n                {\n                    o.ApiVersionReader = new HeaderApiVersionReader(\"X-API-Version\");\n                    o.DefaultApiVersion = new Microsoft.AspNetCore.Mvc.ApiVersion(1, 0);\n\n                    if (_currentEnvironment.IsDevelopment())\n                    {\n                        o.AssumeDefaultVersionWhenUnspecified = true;\n                    }\n                });\n        }\n\n        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.\n        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)\n        {\n            loggerFactory.AddConsole(Configuration.GetSection(\"Logging\"));\n            loggerFactory.AddDebug();\n\n            var provider = new FileExtensionContentTypeProvider();\n            provider.Mappings[\".ps1\"] = \"text/plain\";\n            provider.Mappings[\".py\"] = \"text/plain\";\n            provider.Mappings[\".ace\"] = \"text/plain\";\n\n            app.UseStaticFiles(); // For the wwwroot folder\n\n            app.UseStaticFiles(new StaticFileOptions()\n            {\n                FileProvider = new PhysicalFileProvider(\n                    Path.Combine(Directory.GetCurrentDirectory(), \"scripts\")),\n                RequestPath = new PathString(\"/scripts\"),\n                ContentTypeProvider = provider\n            });\n\n            app.UseExceptionHandler(GlobalExceptionHandler);\n            app.UseMvc();\n        }\n\n        public void GlobalExceptionHandler(IApplicationBuilder builder)\n        {\n            builder.Run(async context =>\n            {\n                context.Response.StatusCode = 500;\n                context.Response.ContentType = \"application/json; charset=utf-8\";\n\n                var error = context.Features.Get<IExceptionHandlerFeature>();\n                var excpetion = error.Error;\n                if (error != null)\n                {\n                    await context.Response.WriteAsync(new ErrorViewModel()\n                    {\n                        Message = excpetion.Message,\n                        StackTrace = excpetion.StackTrace\n                    }.ToString(), Encoding.UTF8);\n                }\n            });\n        }\n    }\n}"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/ViewModels/ArbitrarySweepViewModel.cs",
    "content": "﻿using System;\nusing System.Collections;\nusing System.ComponentModel.DataAnnotations;\n\nnamespace ACEWebService.ViewModels\n{\n    public class ArbitrarySweepViewModel\n    {\n        [Required]\n        public Hashtable Arguments { get; set; }\n        [Required]\n        public Guid[] ComputerId { get; set; }\n        [Required]\n        public string Script { get; set; }\n        [Required]\n        public string Uri { get; set; }\n    }\n}"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/ViewModels/CredentialViewModel.cs",
    "content": "﻿using System.ComponentModel.DataAnnotations;\n\nnamespace ACEWebService.ViewModels\n{\n    public class CredentialViewModel\n    {\n        [Required]\n        public string UserName { get; set; }\n        [Required]\n        public string Password { get; set; }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/ViewModels/DiscoveryActiveDirectoryViewModel.cs",
    "content": "﻿using System;\nusing System.ComponentModel.DataAnnotations;\n\nnamespace ACEWebService.ViewModels\n{\n    public class DiscoveryActiveDirectoryViewModel\n    {\n        [Required]\n        public string Domain { get; set; }\n        [Required]\n        public Guid CredentialId { get; set; }\n    }\n}"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/ViewModels/DiscoveryComputerListViewModel.cs",
    "content": "﻿using System;\nusing System.ComponentModel.DataAnnotations;\n\nnamespace ACEWebService.ViewModels\n{\n    public class DiscoveryComputerListViewModel\n    {\n        [Required]\n        public string[] ComputerName { get; set; }\n        [Required]\n        public Guid CredentialId { get; set; }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/ViewModels/DownloadReceiveViewModel.cs",
    "content": "﻿using System;\nusing System.ComponentModel.DataAnnotations;\n\nnamespace ACEWebService.ViewModels\n{\n    public class DownloadReceiveViewModel\n    {\n        [Required]\n        public string ComputerName { get; set; }\n        [Required]\n        public string Name { get; set; }\n        [Required]\n        public string FullPath { get; set; }\n        [Required]\n        public byte[] Content { get; set; }\n    }\n}"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/ViewModels/DownloadRequestViewModel.cs",
    "content": "﻿using System;\nusing System.ComponentModel.DataAnnotations;\n\nnamespace ACEWebService.ViewModels\n{\n    public class DownloadRequestViewModel\n    {\n        [Required]\n        public Guid ComputerId { get; set; }\n        [Required]\n        public string FilePath { get; set; }\n        [Required]\n        public string Uri { get; set; }\n    }\n}"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/ViewModels/ErrorViewModel.cs",
    "content": "﻿using Newtonsoft.Json;\n\nnamespace VTIProxy.ViewModels\n{\n    public class ErrorViewModel\n    {\n        public string Message { get; set; }\n        public string StackTrace { get; set; }\n\n        public override string ToString()\n        {\n            return JsonConvert.SerializeObject(this);\n        }\n    }\n}"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/ViewModels/FileViewModel.cs",
    "content": "﻿using System.ComponentModel.DataAnnotations;\n\nnamespace ACEWebService.ViewModels\n{\n    public class FileViewModel\n    {\n        [Required]\n        public string Name { get; set; }\n        [Required]\n        public byte[] Content { get; set; }\n        [Required]\n        public string RoutingKey { get; set; }\n        [Required]\n        public string Language { get; set; }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/ViewModels/ScheduleIntervalViewModel.cs",
    "content": "﻿using System.ComponentModel.DataAnnotations;\n\nnamespace ACEWebService.ViewModels\n{\n    public class ScheduleIntervalViewModel\n    {\n        [Required]\n        public string[] ComputerName { get; set; }\n        [Required, RegularExpression(\"[a-zA-Z]+\")]\n        public string ScriptId { get; set; }\n        [Required]\n        public string Uri { get; set; }\n        [Required]\n        public string UserName { get; set; }\n        [Required]\n        public string Password { get; set; }\n        [Required]\n        public int Interval { get; set; }\n    }\n}"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/ViewModels/ScheduleTimeViewModel.cs",
    "content": "﻿using ACEWebService.Entities;\nusing System;\nusing System.ComponentModel.DataAnnotations;\n\nnamespace ACEWebService.ViewModels\n{\n    public class ScheduleTimeViewModel\n    {\n        [Required]\n        public string[] ComputerId { get; set; }\n        [Required]\n        public string ScriptId { get; set; }\n        [Required]\n        public string Uri { get; set; }\n        [Required]\n        public int Hour { get; set; }\n        [Required]\n        public int Minute { get; set; }\n        [Required]\n        public int Interval { get; set; }\n        [Required]\n        public int RepeatCount { get; set; }\n    }\n}"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/ViewModels/SweepExecutionViewModel.cs",
    "content": "﻿using System;\nusing System.ComponentModel.DataAnnotations;\n\nnamespace ACEWebService.ViewModels\n{\n    public class SweepExecutionViewModel\n    {\n        [Required]\n        public Guid[] ComputerId { get; set; }\n\n        [Required]\n        public Guid ScriptId { get; set; }\n\n        [Required]\n        public string Uri { get; set; }\n\n        [Required]\n        public string ExternalUri { get; set; }\n    }\n}"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/ViewModels/SweepResultViewModel.cs",
    "content": "﻿using Newtonsoft.Json.Linq;\nusing System;\nusing System.ComponentModel.DataAnnotations;\n\nnamespace ACEWebService.ViewModels\n{\n    public class SweepResultViewModel\n    {\n        [Required]\n        public string RoutingKey { get; set; }\n\n        [Required]\n        public string ScanId { get; set; }\n\n        [Required]\n        public string[] Data { get; set; }\n    }\n}"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/ViewModels/UserViewModel.cs",
    "content": "﻿using System.ComponentModel.DataAnnotations;\n\nnamespace ACEWebService.ViewModels\n{\n    public class UserViewModel\n    {\n        [Required]\n        public string UserName { get; set; }\n        public string FirstName { get; set; }\n        public string LastName { get; set; }\n        public bool IsAdmin { get; set; }\n    }\n}\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/appsettings.Production.json",
    "content": "﻿{\n  \"Logging\": {\n    \"IncludeScopes\": false,\n    \"LogLevel\": {\n      \"Default\": \"Debug\",\n      \"System\": \"Information\",\n      \"Microsoft\": \"Information\"\n    }\n  },\n\n  \"AppSettings\": {\n    \"RabbitMQServer\": \"[RABBITMQ HOSTNAME]\",\n    \"RabbitMQUserName\": \"[RABBITMQ USERNAME]\",\n    \"RabbitMQPassword\": \"[RABBITMQ PASSWORD]\",\n    \"EncryptionPassphrase\": \"[ENCRYPTION PASSPHRASE]\",\n    \"Thumbprint\": \"[SSL THUMBPRINT]\"\n  },\n\n  \"ConnectionStrings\": {\n    \"DefaultConnection\": \"Server=[SQL HOSTNAME];Database=ACEWebService;User Id=sa;Password=[SQL PASSWORD];MultipleActiveResultSets=true\"\n  }\n}"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/appsettings.json",
    "content": "﻿{\n  \"Logging\": {\n    \"IncludeScopes\": false,\n    \"LogLevel\": {\n      \"Default\": \"Debug\",\n      \"System\": \"Information\",\n      \"Microsoft\": \"Information\"\n    }\n  },\n\n  \"AppSettings\": {\n    \"RabbitMQServer\": \"rabbitmq.ace.local\",\n    \"RabbitMQUserName\": \"ace\",\n    \"RabbitMQPassword\": \"P@ssw0rd!\",\n    \"Thumbprint\": \"5FFD4C6E95D54B4FC1BDB34ABB7384C3424E4EF8\"\n  },\n\n  \"ConnectionStrings\": {\n    \"DefaultConnection\": \"Server=(localdb)\\\\MSSQLLocalDB;Database=ACEWebService;Trusted_Connection=True;MultipleActiveResultSets=true\"\n  }\n}"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/nuget.config",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n  <packageSources>\n    <add key=\"nuget.org\" value=\"https://api.nuget.org/v3/index.json\" />\n    <add key=\"aspnet-contrib\" value=\"https://www.myget.org/F/aspnet-contrib/api/v3/index.json\" />\n    <add key=\"dotnet-core\" value=\"https://dotnet.myget.org/F/dotnet-core/api/v3/index.json\" />\n    <add key=\"powershell-core\" value=\"https://powershell.myget.org/F/powershell-core/api/v3/index.json\" />    \n  </packageSources>\n</configuration>"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/scripts/Download-AceFile.ps1",
    "content": "function Download-AceFile\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Thumbprint,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Path,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Id\n    )\n\n    try\n    {\n        $file = Get-Item -Path $Path -ErrorAction Stop\n        \n        $props = @{\n            ComputerName = (Get-WmiObject Win32_ComputerSystem -Property 'Name','Domain' | ForEach-Object {\"$($_.Name).$($_.Domain)\"})\n            Name = $file.Name\n            FullPath = $file.FullName\n            Content = ([System.IO.File]::ReadAllBytes($file.FullName))\n        }\n\n        Invoke-AceWebRequest -Thumbprint $Thumbprint -Uri \"$($Uri)/ace/download/$($Id)\" -Body (ConvertTo-JsonV2 -InputObject $props)\n    }\n    catch\n    {\n        # Send failure notification\n        Write-Warning \"Can't find file\"\n    }\n}\n\nfunction ConvertTo-JsonV2 \n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        $InputObject\n    )\n\n    Begin \n    {\n        $null = [System.Reflection.Assembly]::LoadWithPartialName(\"System.Web.Extensions\")\n        $Serializer = New-Object System.Web.Script.Serialization.JavaScriptSerializer\n    }\n\n    Process \n    {\n        try \n        {\n            $Serializer.Serialize($InputObject)\n        } \n        catch \n        {\n            # Write error message to ACE to let it know that the scan failed\n            #Invoke-AceWebRequest -Thumbprint $Thumbprint -Uri \"$($Uri)/ace/result/$($SweepId)\" -Body $body\n        }    \n    }\n}\n\nfunction Invoke-AceWebRequest\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Thumbprint,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Body\n    )\n\n    [Net.ServicePointManager]::ServerCertificateValidationCallback = {\n        $Thumbprint = $Thumbprint\n        $certificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]$args[1]\n    \n        if ($certificate -eq $null)\n        {\n            $Host.UI.WriteErrorLine(\"Null certificate.\")\n            return $true\n        }\n    \n        if ($certificate.Thumbprint -eq $Thumbprint)\n        {\n            return $true\n        }\n        else\n        {\n            $Host.UI.WriteErrorLine(\"Thumbprint mismatch. Certificate thumbprint $($certificate.Thumbprint)\")\n        }\n    \n        return $false\n    }\n\n    try\n    {\n        #Write-Host \"URI: $($Uri)\"\n\n        # Create web request\n        $WebRequest = [Net.WebRequest]::Create($uri)\n        $WebRequest.Method = 'Post'\n        $WebRequest.ContentType = 'application/json'\n        $WebRequest.Headers.Add('X-API-Version:1.0')\n\n        $byteArray = [System.Text.Encoding]::UTF8.GetBytes($Body)\n        $Webrequest.ContentLength = $byteArray.Length\n        \n        $dataStream = $Webrequest.GetRequestStream()            \n        $dataStream.Write($byteArray, 0, $byteArray.Length)\n        $dataStream.Close()\n\n        # Get response stream\n        $ResponseStream = $Webrequest.GetResponse().GetResponseStream()\n    \n        # Create a stream reader and read the stream returning the string value.\n        $StreamReader = New-Object System.IO.StreamReader -ArgumentList $ResponseStream\n        $StreamReader.ReadToEnd()\n    }\n    catch\n    {\n        Write-Error \"Failed: $($_.exception.innerexception.message)\"\n    }\n}"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/scripts/Start-AceScript.ps1",
    "content": "function Start-AceScript\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $ServerUri,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $ScriptUri,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Thumbprint,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $SweepId,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $ScanId,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $RoutingKey\n    )\n\n    # Get the FQDN of the target computer and the Timestamp of the scan itself\n    $HostFQDN = Get-WmiObject Win32_ComputerSystem -Property 'Name','Domain' | ForEach-Object {\"$($_.Name).$($_.Domain)\"}\n    $ResultDate = (Get-Date).ToUniversalTime().ToString(\"yyyyMMddThhmmssmsmsZ\")\n\n    # Create a list of strings to put scan results in\n    $dataList = New-Object -TypeName System.Collections.Generic.List['string']\n\n    $script = Invoke-AceWebRequest -Thumbprint $Thumbprint -Uri \"$($ServerUri)$($ScriptUri)\"\n\n    # Download the script to execute from the server\n    foreach($o in (Invoke-Expression $script))\n    {\n        if($o -ne $null)\n        {\n            $o.Add('ComputerName', $HostFQDN)\n            $o.Add('SweepId', $SweepId)\n            $o.Add('ScanId', $ScanId)\n            $o.Add('ResultDate', $ResultDate)\n\n            try\n            {\n                $message = $o | ConvertTo-JsonV2\n                $dataList.Add($message)\n            }\n            catch\n            {\n                # We need to figure out what to do here\n                # This is if ConvertTo-JsonV2 throws an error\n                # Invoke-AceWebRequest -Thumbprint $Thumbprint -Uri \"$($Uri)/ace/result/$($SweepId)\" -Body $body\n            }\n        }\n    }\n\n    # Send 200 results at a time\n    # This keeps us under the Kestrel request size limit of 30MB\n    for($i = 0; $i -lt $dataList.Count; $i += 200)\n    {\n        $props = @{\n            RoutingKey   = $RoutingKey\n            ScanId       = $ScanId\n            Data         = $dataList[$i..($i+199)]\n        }\n\n        # Submit the results to the server\n        Invoke-AceWebRequest -Thumbprint $Thumbprint -Uri \"$($ServerUri)/ace/result/$($SweepId)\" -Body (ConvertTo-JsonV2 -InputObject $props) -Method Post\n    }\n}\n\nfunction ConvertTo-JsonV2 \n{\n    param\n    (\n        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]\n        [hashtable[]]\n        $InputObject\n    )\n\n    Begin \n    {\n        $null = [System.Reflection.Assembly]::LoadWithPartialName(\"System.Web.Extensions\")\n        $Serializer = New-Object System.Web.Script.Serialization.JavaScriptSerializer\n    }\n\n    Process \n    {\n        foreach($item in $InputObject)\n        {\n            $Serializer.Serialize($item)\n        }\n    }\n}\n\n# Need to update to accept GET requests\nfunction Invoke-AceWebRequest\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n        [Parameter()]\n        [string]\n        $ApiKey,\n\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Thumbprint,\n\n        [Parameter()]\n        [ValidateSet('Delete','Get','Post','Put')]\n        [string]\n        $Method = 'Get',\n\n        [Parameter()]\n        [string]\n        $ContentType = 'application/json',\n\n        [Parameter()]\n        [string]\n        $Body\n    )\n    Try\n    {\n        # Create web request\n        $WebRequest = [System.Net.WebRequest]::Create($Uri)\n    \n        $WebRequest.Headers.Add('X-API-Version:1.0')\n        \n        if($PSBoundParameters.ContainsKey('ApiKey'))\n        {\n            $webrequest.Headers.Add(\"X-ApiKey:$($ApiKey)\")\n        }\n\n        $WebRequest.Method = $Method\n        $WebRequest.ContentType = $ContentType\n\n        # Set the callback to check for null certificate and thumbprint matching.\n        $WebRequest.ServerCertificateValidationCallback = {\n            \n            $certificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]$args[1]\n            \n            if ($certificate -eq $null)\n            {\n                $Host.UI.WriteWarningLine(\"Null certificate.\")\n                return $true\n            }\n    \n            if ($certificate.Thumbprint -eq $Thumbprint)\n            {\n                return $true\n            }\n            else\n            {\n                $Host.UI.WriteWarningLine(\"Thumbprint mismatch. Certificate thumbprint $($certificate.Thumbprint)\")\n                $Host.UI.WriteWarningLine(\"   Expected thumbprint: $($Thumbprint)\")\n                $Host.UI.WriteWarningLine(\"   Received thumbprint: $($certificate.Thumbprint)\")\n            }\n    \n            return $false\n        }\n\n        if($PSBoundParameters.ContainsKey('Body'))\n        {\n            $byteArray = [System.Text.Encoding]::UTF8.GetBytes($Body)\n            $Webrequest.ContentLength = $byteArray.Length\n            \n            $dataStream = $Webrequest.GetRequestStream()            \n            $dataStream.Write($byteArray, 0, $byteArray.Length)\n            $dataStream.Close()\n        }\n\n        # Get response stream\n        $ResponseStream = $webrequest.GetResponse().GetResponseStream()\n    \n        # Create a stream reader and read the stream returning the string value.\n        $StreamReader = New-Object System.IO.StreamReader -ArgumentList $ResponseStream\n        $StreamReader.ReadToEnd()\n\n        $StreamReader.Close()\n        $ResponseStream.Close()\n    }\n    catch\n    {\n        Write-Error \"Failed: $($_.exception.innerexception.message)\"\n    }\n}"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/web.config",
    "content": "﻿<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n\n  <!--\n    Configure your application settings in appsettings.json. Learn more at http://go.microsoft.com/fwlink/?LinkId=786380\n  -->\n  \n  <system.webServer>\n    <handlers>\n      <add name=\"aspNetCore\" path=\"*\" verb=\"GET,HEAD,POST,DEBUG,PUT,DELETE,OPTIONS\" modules=\"AspNetCoreModule\" resourceType=\"Unspecified\"/>\n    </handlers>\n    <aspNetCore processPath=\"%LAUNCHER_PATH%\" arguments=\"%LAUNCHER_ARGS%\" stdoutLogEnabled=\"false\" stdoutLogFile=\".\\logs\\stdout\" forwardWindowsAuthToken=\"false\"/>\n  </system.webServer>\n</configuration>"
  },
  {
    "path": "LICENSE-Quartz.NET",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License."
  },
  {
    "path": "LICENSE-RabbitMQ",
    "content": "This package, the RabbitMQ .NET client library, is dual-licensed under\nthe Apache License v2 and the Mozilla Public License v1.1.\n\nFor the Apache License, please see the file LICENSE-APACHE2.\n\nFor the Mozilla Public License, please see the file LICENSE-MPL-RabbitMQ.\n\nFor attribution of copyright and other details of provenance, please\nrefer to the source code.\n\nIf you have any questions regarding licensing, please contact us at \ninfo@rabbitmq.com."
  },
  {
    "path": "LICENSE-SSH.NET",
    "content": "\nThe MIT License (MIT)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE."
  },
  {
    "path": "LICENSE-osxcollector",
    "content": "This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.\n\nThis program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/."
  },
  {
    "path": "README.md",
    "content": "# Automated Collection and Enrichment\nThe Automated Collection and Enrichment (ACE) platform is a suite of tools for threat hunters to collect data from many endpoints in a network and automatically enrich the data. The data is collected by running scripts on each computer without installing any software on the target. ACE supports collecting from Windows, macOS, and Linux hosts.\n\nACE is meant to simplify the process of remotely collecting data across an environment by offering credential management, scheduling, centralized script management, and remote file downloading. ACE is designed to complement a SIEM by collecting data and enriching data; final analysis is best suited for SIEM tools such as Splunk, ELK, or the tools the analyst prefers.\n\n![alt text](resources/images/ACE_Infrastructure.png \"ACE Infrastructure\")\n\n## Why use ACE?\nACE grew out of the need to perform Compromise Assessments in places with common restrictions:\n* A dedicated software agent cant be installed on the target hosts.\n* Copying and running executables (such as Sysinternals tools) is not feasible.\n* The customer cannot enable Windows Remoting (WinRM).\n* The customers visibility into macOS/Linux hosts is limited or nonexistent.\n* New scripts/tools must be created for customer-specific data.\n* Network segmentation requires multiple credentials to access all machines in the environment.\n\n\n## Installation/What is the architecture of ACE?\nACE has four components: the ACE Web Service, the ACE Nginx web proxy, the ACE SQL database, and the ACE RabbitMQ message queue. The Web Service is a RESTful API that takes requests from clients to schedule and manage scans. The SQL database stores the configuration and data from scans. The RabbitMQ service handles automated enrichment of data.\n\n1) Identify the IP Address of both your Linux Docker host and your Windows host.\n\n### ACE Docker Images\n\n### ACEWebService\n1) Download the Configure-AceWebService.ps1 script from the Release page\n2) \n\n## Usage/How do I use ACE?\nThe ACE repository includes a collection of PowerShell scripts to interact with the ACE Web Service, including adding users, managing credentials, uploading collection scripts, and scheduling scans. \n\nAfter deploying the ACE servers, use **New-AceUser** to create a new ACE user.\n\nRemove the default Admin user with **Remove-AceUser**.\n\nUse **New-AceCredential** to enter a set of credentials.\n\nRun **Start-AceDiscovery** to automatically find computers on the Windows domain.\n\nRun **Start-AceSweep** to start a sweep to run the selected scripts across the discovered endpoints.\n\n\n\n## More Resources\n* [ACE GitHub Wiki](https://github.com/Invoke-IR/ACE/wiki)\n* [ACE BlackHat Arsenal slides](https://www.slideshare.net/JaredAtkinson/automated-collection-and-enrichment-ace)\n\n## Contributing\nContributions to ACE are always welcome.\n"
  }
]