Full Code of Invoke-IR/ACE for AI

master f5abdfdef562 cached
159 files
1.2 MB
294.7k tokens
216 symbols
1 requests
Download .txt
Showing preview only (1,301K chars total). Download the full file or copy to clipboard to get everything.
Repository: Invoke-IR/ACE
Branch: master
Commit: f5abdfdef562
Files: 159
Total size: 1.2 MB

Directory structure:
gitextract_n0h_95a4/

├── ACE-Docker/
│   ├── README.md
│   ├── ace-ca/
│   │   └── dockerfile
│   ├── ace-nginx/
│   │   ├── Dockerfile
│   │   ├── README.md
│   │   ├── entrypoint.sh
│   │   └── nginx.conf
│   ├── ace-rabbitmq/
│   │   ├── Dockerfile
│   │   ├── README.md
│   │   ├── ace-cache.py
│   │   ├── ace-entrypoint.sh
│   │   └── ace-lookup.py
│   ├── ace-sql/
│   │   ├── Dockerfile
│   │   ├── README.md
│   │   ├── ace.sql
│   │   └── import-data.sh
│   ├── ace.env
│   ├── docker-compose.yml
│   ├── settings.sh
│   └── start.sh
├── ACE-Management/
│   └── PS-ACE/
│       ├── Cmdlets/
│       │   ├── Download-AceFile.ps1
│       │   ├── Get-AceComputer.ps1
│       │   ├── Get-AceCredential.ps1
│       │   ├── Get-AceSchedule.ps1
│       │   ├── Get-AceScript.ps1
│       │   ├── Get-AceSweep.ps1
│       │   ├── Get-AceSweepResult.ps1
│       │   ├── Get-AceUser.ps1
│       │   ├── Invoke-AceWebRequest.ps1
│       │   ├── New-AceCredential.ps1
│       │   ├── New-AceScheduledScan.ps1
│       │   ├── New-AceScript.ps1
│       │   ├── New-AceUser.ps1
│       │   ├── Remove-AceCredential.ps1
│       │   ├── Remove-AceScript.ps1
│       │   ├── Remove-AceUser.ps1
│       │   ├── Send-AceResult.ps1
│       │   ├── Start-AceDiscovery.ps1
│       │   ├── Start-AceSweep.ps1
│       │   ├── Update-AceCredential.ps1
│       │   └── Update-AceUser.ps1
│       ├── PS-ACE.psm1
│       ├── README.md
│       ├── Scripts/
│       │   ├── ACE-Master.ps1
│       │   ├── ACE_Get-AccessToken.ps1
│       │   ├── ACE_Get-ArpCache.ps1
│       │   ├── ACE_Get-Atom.ps1
│       │   ├── ACE_Get-InjectedThread.ps1
│       │   ├── ACE_Get-KerberosTicketCache.ps1
│       │   ├── ACE_Get-LogonSession.ps1
│       │   ├── ACE_Get-MasterBootRecord.ps1
│       │   ├── ACE_Get-NetworkConnection.ps1
│       │   ├── ACE_Get-PSAutorun.ps1
│       │   ├── ACE_Get-PSIProcess.ps1
│       │   ├── ACE_Get-PSIScheduledTask.ps1
│       │   ├── ACE_Get-PSIService.ps1
│       │   ├── ACE_Get-PSIWindowsSecurityEvent.ps1
│       │   ├── ACE_Get-ScheduledJob.ps1
│       │   ├── ACE_Get-SecurityPackage.ps1
│       │   ├── ACE_Get-SimpleNamedPipe.ps1
│       │   └── Invoke-MonsterWinRM.ps1
│       └── Working/
│           └── ACE_Get-PSIPrefetch.ps1
├── ACE-WebService/
│   ├── .gitignore
│   ├── ACEWebService.sln
│   ├── Configure-AceWebService.ps1
│   ├── NuGet.config
│   ├── dockerfile
│   └── src/
│       └── ACEWebService/
│           ├── ACEWebService.csproj
│           ├── App.config
│           ├── AppSettings.cs
│           ├── Controllers/
│           │   ├── ComputerController.cs
│           │   ├── CredentialController.cs
│           │   ├── DiscoverController.cs
│           │   ├── DownloadController.cs
│           │   ├── ResultController.cs
│           │   ├── ScanController.cs
│           │   ├── ScriptController.cs
│           │   ├── SweepController.cs
│           │   └── UserController.cs
│           ├── DbModelBuilder.cs
│           ├── Entities/
│           │   ├── ACEWebServiceDbContext.cs
│           │   ├── Computer.cs
│           │   ├── ComputerGroup.cs
│           │   ├── Credential.cs
│           │   ├── Download.cs
│           │   ├── Scan.cs
│           │   ├── Schedule.cs
│           │   ├── Script.cs
│           │   ├── Sweep.cs
│           │   └── User.cs
│           ├── Migrations/
│           │   ├── 20170322221439_MyFirstMigration.Designer.cs
│           │   ├── 20170322221439_MyFirstMigration.cs
│           │   ├── 20170322222622_MySecondMigration.Designer.cs
│           │   ├── 20170322222622_MySecondMigration.cs
│           │   ├── 20170417201050_MyThirdMigration.Designer.cs
│           │   ├── 20170417201050_MyThirdMigration.cs
│           │   ├── 20170420231736_MyFourthMigration.Designer.cs
│           │   ├── 20170420231736_MyFourthMigration.cs
│           │   ├── 20170421030619_MyFifthMigration.Designer.cs
│           │   ├── 20170421030619_MyFifthMigration.cs
│           │   ├── 20170429215921_MySixthMigration.Designer.cs
│           │   ├── 20170429215921_MySixthMigration.cs
│           │   ├── 20170430141205_MySeventhMigration.Designer.cs
│           │   ├── 20170430141205_MySeventhMigration.cs
│           │   ├── 20170707032113_MyEigthMigration.Designer.cs
│           │   ├── 20170707032113_MyEigthMigration.cs
│           │   ├── 20170707040959_MyNinthMigration.Designer.cs
│           │   ├── 20170707040959_MyNinthMigration.cs
│           │   ├── 20170707042221_MyTenthMigration.Designer.cs
│           │   ├── 20170707042221_MyTenthMigration.cs
│           │   ├── 20170713053904_MyEleventhMigration.Designer.cs
│           │   ├── 20170713053904_MyEleventhMigration.cs
│           │   ├── 20171116210534_MyTwelfthMigration.Designer.cs
│           │   ├── 20171116210534_MyTwelfthMigration.cs
│           │   ├── 20171116211023_MyThirteenthMigration.Designer.cs
│           │   ├── 20171116211023_MyThirteenthMigration.cs
│           │   ├── 20171116233431_MyFourteenthMigration.Designer.cs
│           │   ├── 20171116233431_MyFourteenthMigration.cs
│           │   └── ACEWebServiceDbContextModelSnapshot.cs
│           ├── Program.cs
│           ├── Project_Readme.html
│           ├── Properties/
│           │   ├── PublishProfiles/
│           │   │   ├── ACEWebService-publish.ps1
│           │   │   ├── ACEWebService.pubxml
│           │   │   ├── FileSystem-publish.ps1
│           │   │   ├── FileSystem.pubxml
│           │   │   └── publish-module.psm1
│           │   └── launchSettings.json
│           ├── Security/
│           │   ├── ApiKeyPolicy.cs
│           │   └── IsAdminPolicy.cs
│           ├── Services/
│           │   ├── IAceConfiguration.cs
│           │   ├── ICryptographyService.cs
│           │   ├── IDiscoveryService.cs
│           │   ├── IDownloadService.cs
│           │   ├── ISweepExecutionService.cs
│           │   └── ISweepResultProcessorService.cs
│           ├── Startup.cs
│           ├── ViewModels/
│           │   ├── ArbitrarySweepViewModel.cs
│           │   ├── CredentialViewModel.cs
│           │   ├── DiscoveryActiveDirectoryViewModel.cs
│           │   ├── DiscoveryComputerListViewModel.cs
│           │   ├── DownloadReceiveViewModel.cs
│           │   ├── DownloadRequestViewModel.cs
│           │   ├── ErrorViewModel.cs
│           │   ├── FileViewModel.cs
│           │   ├── ScheduleIntervalViewModel.cs
│           │   ├── ScheduleTimeViewModel.cs
│           │   ├── SweepExecutionViewModel.cs
│           │   ├── SweepResultViewModel.cs
│           │   └── UserViewModel.cs
│           ├── appsettings.Production.json
│           ├── appsettings.json
│           ├── nuget.config
│           ├── scripts/
│           │   ├── Download-AceFile.ps1
│           │   └── Start-AceScript.ps1
│           └── web.config
├── LICENSE-Quartz.NET
├── LICENSE-RabbitMQ
├── LICENSE-SSH.NET
├── LICENSE-osxcollector
└── README.md

================================================
FILE CONTENTS
================================================

================================================
FILE: ACE-Docker/README.md
================================================
# ACE-Docker
This project focuses on simplifying ACE's deployment process as much as possible.

## Goals

## Components

### [specterops/ace-mssql-linux](https://hub.docker.com/r/specterops/ace-mssql-linux/)
MSSQL 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.

### [specterops/ace-rabbitmq](https://hub.docker.com/r/specterops/ace-rabbitmq/)
RabbitMQ 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.

### [specterops/ace-nginx](https://hub.docker.com/r/specterops/ace-nginx/)
NGINX HTTP(S) Reverse Proxy. Proxy's access to the ACE Web Application and provides SSL Certificates for those connections.

## Getting Started
Our 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:
* Install Docker
* If on Linux, Install Docker Compose
* Adjust Docker preferences to allow containers to use 4GBs of RAM (Docker -> Preferences -> Advanced -> Memory)
* Download this repository
* Execute start.sh

start.sh is a simple shell script that accomplishes the remaining set up steps. Below is a list of tasks accomplished by start.sh:
* Create SSL certificate
* Add SSL Thumbprint to the ACE Web Application's appsettings.json file
* Build ACE Docker images with Docker Compose
* Start ACE Docker containers

================================================
FILE: ACE-Docker/ace-ca/dockerfile
================================================
FROM cfssl/cfssl:latest

RUN cfssl print-defaults config > ca-config.json && cfssl print-defaults csr > ca-csr.json \  
&& cfssl genkey -initca ca-csr.json | cfssljson -bare ca

EXPOSE 8888

ENTRYPOINT ["cfssl"]

CMD ["serve","-ca=ca.pem","-ca-key=ca-key.pem","-address=0.0.0.0"]

================================================
FILE: ACE-Docker/ace-nginx/Dockerfile
================================================
FROM nginx
MAINTAINER Jared Atkinson <jared@invoke-ir.com>
RUN apt-get update; apt-get install -y openssl
COPY ./nginx.conf /etc/nginx/nginx.conf
COPY ./entrypoint.sh /opt/entrypoint.sh
RUN chmod +x /opt/entrypoint.sh
CMD /bin/bash /opt/entrypoint.sh && nginx -c /etc/nginx/nginx.conf -g "daemon off;"

================================================
FILE: ACE-Docker/ace-nginx/README.md
================================================
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). 

ACE relies on SSL for two important features: 
* Encryption - Data sent to and from the ACE Web Application is encrypted
* Authentication - Certificate pinning is used to provide server side authentication to avoid Man-in-the-Middle attacks.

## Using this Image
The ACE Nginx can be run in a couple different ways. 
### Standalone
If you are running ACE in a test/development/standalone deployment, then you can simply run the container as shown below.
```
docker run --name ace-nginx -p 80:80 -p 443:443 -d specterops/ace-nginx
```
### Clustered/Redundant
If 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. 

Simply create a docker volume (it can be named "certs" or whatever you choose).
```
docker volume create --name certs
```

Then 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.
```
docker run --name ace-nginx -v certs:/etc/nginx/certs -p 80:80 -p 443:443 -d specterops/ace-nginx
```

### Get SSL Certificate Thumbprint
The .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:
```
docker logs ace-nginx
################################################################
# ACE SSL Thumbprint: 3179CC1A0A0E20477260BFB8D559F35240297E6B #
################################################################
```

================================================
FILE: ACE-Docker/ace-nginx/entrypoint.sh
================================================
#!/bin/sh

# Add Environment Variable to nginx.conf
sed -i -e 's/\[WEBSERVICE_IP\]/'"$WEBSERVICE_IP"'/g' /etc/nginx/nginx.conf

# Check if /etc/nginx/certs directory exits
if [ ! -d /etc/nginx/certs ]; then
    mkdir /etc/nginx/certs
fi

# Check if SSL Cert exists, if it doesn't then make it
if [ ! -f /etc/nginx/certs/server.crt ]; then
    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
fi

# Get and output SSL Thumbprint
fingerprint=$(openssl x509 -in /etc/nginx/certs/server.crt -noout -fingerprint | sed 's/SHA1 Fingerprint=//g' |  sed 's/://g')
echo "\"Thumbprint\": \"$fingerprint\","

================================================
FILE: ACE-Docker/ace-nginx/nginx.conf
================================================
worker_processes 4;

events { worker_connections 1024; }

http {
    # Allow files of <= 2MB to be uploaded
    client_max_body_size 2M;

    # Act as Load Balancer for 4 nodes
    upstream web.ace.local {
        server [WEBSERVICE_IP]:80;
#        server dockernginxkestrel_core-app_2:80;
#        server dockernginxkestrel_core-app_3:80;
#        server dockernginxkestrel_core-app_4:80;
    }

    # Redirect all HTTP traffic to HTTPS
    server {
      listen 80;
      return 301 https://$host$request_uri;
    }
    
    # HTTPS Server
    server {
        # Listen on port 443
        listen 443;

        # Server name. You need a DNS record (or add this hostname to your hosts file)
        server_name web.ace.local;

        # Digital certificates generated with makecert.sh / makecert.bat
        ssl_certificate     /etc/nginx/certs/server.crt;
        ssl_certificate_key /etc/nginx/certs/server.key;

        # SSL configuration
        ssl on;
        ssl_session_cache  builtin:1000  shared:SSL:10m;
        ssl_protocols  TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers HIGH:!aNULL:!eNULL:!EXPORT:!CAMELLIA:!DES:!MD5:!PSK:!RC4;
        ssl_prefer_server_ciphers on;

        # Location configuration to use the core-app.local upstream defined before
        location / {
            proxy_pass          http://web.ace.local;
            proxy_read_timeout  90;
            proxy_set_header        Host $host;
            proxy_set_header        X-Real-IP $remote_addr;
            proxy_set_header        X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header        X-Forwarded-Proto $scheme;       

            proxy_redirect      http://localhost https://web.ace.local;
        }
    }
}

================================================
FILE: ACE-Docker/ace-rabbitmq/Dockerfile
================================================
FROM  rabbitmq:3-management
MAINTAINER Jared Atkinson <jared@invoke-ir.com>
ADD ace-entrypoint.sh /root/ace-entrypoint.sh
ADD ace-cache.py /root/ace-cache.py
ADD ace-lookup.py /root/ace-lookup.py
RUN \
    chmod +x /root/ace-entrypoint.sh \
    && chmod +x /root/ace-cache.py \
    && chmod +x /root/ace-lookup.py \
    && apt-get update -y \
    && apt-get upgrade -y \
    && apt-get dist-upgrade -y \
    && apt-get install -y python2.7 python-pip \
    && pip install pika requests
CMD \
    /usr/local/bin/docker-entrypoint.sh rabbitmq-server > /dev/null & \
    sleep 30 \
    && /root/ace-entrypoint.sh

================================================
FILE: ACE-Docker/ace-rabbitmq/README.md
================================================
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).

## Requirements
* This image requires Docker Engine 1.8+ in any of their supported platforms.
* Requires the following environment flags
* RABBITMQ_DEFAULT_USER=<username>
* RABBITMQ_DEFAULT_PASS=<your_strong_password>
* APIKEY=<virustotal_apikey>

## Using this Image
### Run
```
docker 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
```
# For Persistence
If 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

### Environment Variables
* **RABBITMQ_DEFAULT_USER** Username for RabbitMQ server. Will be used to connect to server and log into management interface.
* **RABBITMQ_DEFAULT_PASS** Password for RabbitMQ server. Will be used to connect to server and log into management interface.
* **APIKEY** Public VirusTotal API key. Allows for lookups of hashes on VirusTotal

================================================
FILE: ACE-Docker/ace-rabbitmq/ace-cache.py
================================================
#!/usr/bin/env python
import json
import sys
import pika
import requests
from argparse import ArgumentParser
from json import dumps

# Our local cache of hashes. Each of the consumers checks this dictionary first
# before doing a lookup against VirusTotal to save time and API queries
cachedEntries = {}

class CachedConsumer(object):
    """A consumer that receives hashes and queries the VirusTotal api
    to find if VirusTotal has any matching hashes, and how many positive
    (malicious) results for that hash.
    """
    EXCHANGE = 'ace_exchange'
    EXCHANGE_TYPE = 'topic'

    def __init__(self, connection):
        """Create a new instance of LookupConsumer, passing in the API key to use.

        :param connection connection: A pika connection object.
        """
        self._connection = connection
        self._channel = None

    def consume_message(self, channel, method, properties, body):
        """Consume a message from channel. This function is passed as a callback
        to basic_consume. After checking the body of the message, the consumer checks the
        cache and either publish the cached entry, or perform a lookup and add the result
        to the cache.
        """
        self._channel = channel
        message = json.loads(body) # parse the JSON results from the message
        newRoutingKey = ""
        if 'SHA256Hash' in message and message['SHA256Hash'] is not None:
            sha256hash = message['SHA256Hash'] # assign the value temporarily instead of doing a lookup each time
            if sha256hash in cachedEntries: #hash is cached
                print "Hash is cached"
                message[u"VTRecordExists"] = cachedEntries[sha256hash][u"VTRecordExists"]
                if u"VTPositives" in cachedEntries[sha256hash]:
                    message[u"VTPositives"] = cachedEntries[sha256hash][u"VTPositives"]
                enrichment,newRoutingKey = method.routing_key.split(".",1)
                self.publish_message(method, message, newRoutingKey)
            elif u'VTRecordExists' in message: #needs to be cached
                print "Adding hash to cache"
                cachedEntries[sha256hash] = {}
                cachedEntries[sha256hash][u"VTRecordExists"] = message[u"VTRecordExists"]
                if u'VTPositives' in message:
                    cachedEntries[sha256hash][u'VTPositives'] = message[u'VTPositives']
                enrichment,newRoutingKey = method.routing_key.split(".",1)
                self.publish_message(method, message, newRoutingKey)
            else: #send for lookup
                print "sending to VT"
                newRoutingKey = "lookup." + method.routing_key
                self.publish_message(method, message, newRoutingKey)
                self._connection.sleep(1)
        elif message['SHA256Hash'] is None:
            print "Hash is null"
            enrichment,newRoutingKey = method.routing_key.split(".",1)
            self.publish_message(method, message, newRoutingKey)

    def publish_message(self, method, message, routingKey):
        """Publish a message to the channel with the new routing key after enrichment.
        """
        body = json.dumps(message)
        channel = self._channel
        channel.basic_ack(delivery_tag = method.delivery_tag)
        channel.basic_publish(exchange=self.EXCHANGE, routing_key=routingKey,body=body, properties=pika.BasicProperties(delivery_mode = 2,))

def main():
    parser = ArgumentParser()
    parser.add_argument(
        '-s', '--Server', dest='rabbitmq_server', default='',
        help='[MANDATORY] RabbitMQ server hostname or IP address')
    parser.add_argument(
        '-u', '--User', dest='rabbitmq_user', default='',
        help='[OPTIONAL] RabbitMQ username')
    parser.add_argument(
        '-p', '--Password', dest='rabbitmq_password', default='',
        help='[OPTIONAL] RabbitMQ password')

    args = parser.parse_args()
    try:
        if (args.rabbitmq_password != '' and args.rabbitmq_user != ''):
            creds = pika.PlainCredentials(args.rabbitmq_user, args.rabbitmq_password)
            connection = pika.BlockingConnection(pika.ConnectionParameters(host=args.rabbitmq_server,
                                            credentials=creds))
        elif (args.rabbitmq_server != ''):
            connection = pika.BlockingConnection(pika.ConnectionParameters(host=args.rabbitmq_server))
        else:
            print("Must provide command line parameters, run 'python ACE_RabbitMQ.py -h' for help")
            return
        channel = connection.channel()
    except:
        print("Issue connecting to RabbitMQ,")

    channel.exchange_declare(exchange='ace_exchange',exchange_type='topic', durable=True)

    channel.queue_declare(queue='siem', durable=True)
    channel.queue_declare(queue='cached_hash', durable=True)
    channel.queue_declare(queue='lookup', durable=True)
    channel.queue_declare(queue='status', durable=True)

    channel.queue_bind(exchange='ace_exchange', queue='siem', routing_key='siem')
    channel.queue_bind(exchange='ace_exchange', queue='cached_hash', routing_key='hash.#')
    channel.queue_bind(exchange='ace_exchange', queue='lookup', routing_key='lookup.hash.#')
    channel.queue_bind(exchange='ace_exchange', queue='status', routing_key='status')
    channel.basic_qos(prefetch_count=1)


    print("Waiting for messages")

    cacheConsume = CachedConsumer(connection)

    channel.basic_consume(cacheConsume.consume_message, queue='cached_hash')

    channel.start_consuming()
    
    connection.close()

if __name__ == '__main__':
    main()

================================================
FILE: ACE-Docker/ace-rabbitmq/ace-entrypoint.sh
================================================
#!/bin/bash
python /root/ace-lookup.py -s 127.0.0.1 -u $RABBITMQ_DEFAULT_USER -p $RABBITMQ_DEFAULT_PASS -k $APIKEY &
python /root/ace-cache.py -s 127.0.0.1 -u $RABBITMQ_DEFAULT_USER -p $RABBITMQ_DEFAULT_PASS &

echo "\"RabbitMQUserName\": \"$RABBITMQ_DEFAULT_USER\","
echo "\"RabbitMQPassword\": \"$RABBITMQ_DEFAULT_PASS\","

while true; do :; sleep 600; done

================================================
FILE: ACE-Docker/ace-rabbitmq/ace-lookup.py
================================================
#!/usr/bin/env python
import json
import sys
import pika
import requests
from argparse import ArgumentParser
from json import dumps

class VTConsumer(object):
    """A consumer that receives hashes and queries the VirusTotal api
    to find if VirusTotal has any matching hashes, and how many positive
    (malicious) results for that hash.
    """
    EXCHANGE = 'ace_exchange'
    EXCHANGE_TYPE = 'topic'

    def __init__(self, api_key, connection):
        """Create a new instance of VTConsumer, passing in the API key to use.

        :param str api_key: The VirusTotal API key to use.
        :param connection connection: A pika connection object.
        """
        self._apikey = api_key
        self._connection = connection
        self._channel = None

    def consume_message(self, channel, method, properties, body):
        """Consume a message from channel. This function is passed as a callback
        to basic_consume. After checking the body of the message, the consumer checks the
        cache and either publish the cached entry, or perform a lookup and add the result
        to the cache.
        """
        self._channel = channel
        message = json.loads(body) # parse the JSON results from the message
        entry = {}
        sha256hash = message['SHA256Hash']
        entry = self.lookup_hash(sha256hash)
        print entry
        if u'VTRecordExists' in entry:
            message[u"VTRecordExists"] = entry[u"VTRecordExists"]
        if u'VTPositives' in entry:
            message[u'VTPositives'] = entry[u'VTPositives']
        self.publish_message(method, message)

    def lookup_hash(self, sha256hash):
        """Perform a lookup against VirusTotal for a given hash.

        :param str vt_hash: A SHA256Hash to check against the VirusTotal API.
        """
        params = { 'apikey': self._apikey, 'resource': sha256hash }
        headers = {"Accept-Encoding": "gzip, deflate", "User-Agent" : "gzip, VirusTotal ACE Enrichment Consumer v0.1"}
        response = requests.get('https://www.virustotal.com/vtapi/v2/file/report', params=params, headers=headers)
        if response.status_code == 204:
            self._connection.sleep(60)
            response = requests.get('https://www.virustotal.com/vtapi/v2/file/report', params=params, headers=headers)
        json_response = response.json()
        if json_response['response_code'] == 1:
            new_record = {}
            new_record[u"VTRecordExists"] = u"True"
            new_record[u"VTPositives"] = json_response['positives']
        elif json_response['response_code'] == 0:
            new_record = {}
            new_record[u"VTRecordExists"] = u"False"
        elif json_response['response_code'] == -2:
            new_record = {}
            new_record[u"VTRecordExists"] = u"False"
        return new_record

    def publish_message(self, method, message):
        """Publish a message to the channel with the new routing key after enrichment.
        """
        enrichment,newRoutingKey = method.routing_key.split(".",1)
        body = json.dumps(message)
        channel = self._channel
        channel.basic_ack(delivery_tag = method.delivery_tag)
        channel.basic_publish(exchange=self.EXCHANGE, routing_key=newRoutingKey,body=body, properties=pika.BasicProperties(delivery_mode = 2,))

def main():
    parser = ArgumentParser()
    parser.add_argument(
        '-s', '--Server', dest='rabbitmq_server', default='',
        help='[MANDATORY] RabbitMQ server hostname or IP address')
    parser.add_argument(
        '-u', '--User', dest='rabbitmq_user', default='',
        help='[OPTIONAL] RabbitMQ username')
    parser.add_argument(
        '-p', '--Password', dest='rabbitmq_password', default='',
        help='[OPTIONAL] RabbitMQ password')
    parser.add_argument(
        '-k', '--APIKey', dest='VTAPIKey', default='',
        help='[MANDATORY] VirusTotal API Key')

    args = parser.parse_args()
    try:
        if (args.VTAPIKey == ''):
            print("Must provide command line parameters, run 'python ACE_RabbitMQ.py -h' for help")
            return
        if (args.rabbitmq_password != '' and args.rabbitmq_user != ''):
            creds = pika.PlainCredentials(args.rabbitmq_user, args.rabbitmq_password)
            connection = pika.BlockingConnection(pika.ConnectionParameters(host=args.rabbitmq_server,
                                            credentials=creds))
        elif (args.rabbitmq_server != ''):
            connection = pika.BlockingConnection(pika.ConnectionParameters(host=args.rabbitmq_server))
        else:
            print("Must provide command line parameters, run 'python ACE_RabbitMQ.py -h' for help")
            return
        channel = connection.channel()
    except:
        print("Issue connecting to RabbitMQ,")

    channel.exchange_declare(exchange='ace_exchange',exchange_type='topic', durable=True)

    channel.queue_declare(queue='siem', durable=True)
    channel.queue_declare(queue='cached_hash', durable=True)
    channel.queue_declare(queue='lookup', durable=True)
    channel.queue_declare(queue='status', durable=True)

    channel.queue_bind(exchange='ace_exchange', queue='siem', routing_key='siem')
    channel.queue_bind(exchange='ace_exchange', queue='cached_hash', routing_key='hash.#')
    channel.queue_bind(exchange='ace_exchange', queue='lookup', routing_key='lookup.hash.#')
    channel.queue_bind(exchange='ace_exchange', queue='status', routing_key='status')
    channel.basic_qos(prefetch_count=1)


    print("Waiting for messages")

    consumer = VTConsumer(args.VTAPIKey, connection)
    channel.basic_consume(consumer.consume_message, queue='lookup')

    channel.start_consuming()

    connection.close()

if __name__ == '__main__':
    main()

================================================
FILE: ACE-Docker/ace-sql/Dockerfile
================================================
FROM microsoft/mssql-server-linux
MAINTAINER Jared Atkinson <jared@invoke-ir.com>

ENV ACCEPT_EULA Y

# Create app directory
RUN mkdir -p /usr/src/ace
WORKDIR /usr/src/ace

# Copy files to container
COPY import-data.sh /usr/src/ace
COPY ace.sql /usr/src/ace

# Grant permissions for the import-data script to be executable
RUN chmod +x /usr/src/ace/import-data.sh

CMD /bin/bash /usr/src/ace/import-data.sh

================================================
FILE: ACE-Docker/ace-sql/README.md
================================================
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).
 
## Requirements
* This image requires Docker Engine 1.8+ in any of their supported platforms.
* 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.
* Requires the following environment flags
* SA_PASSWORD=<your_strong_password>
* A strong system administrator (SA) password: At least 8 characters including uppercase, lowercase letters, base-10 digits and/or non-alphanumeric symbols.

## Using this Image
### Run
```
docker run --name ace-sql -e 'SA_PASSWORD=yourStrong(!)Password' -e 'MSSQL_PID=Standard' -p 1433:1433 -d specterops/ace-sql
```
### For Persistence
If 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

### Environment Variables
* **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.

================================================
FILE: ACE-Docker/ace-sql/ace.sql
================================================
CREATE TABLE [dbo].[Credentials] (
    [Id]       UNIQUEIDENTIFIER NOT NULL,
    [Password] NVARCHAR (MAX)   NOT NULL,
    [UserName] NVARCHAR (MAX)   NOT NULL,
    CONSTRAINT [PK_Credentials] PRIMARY KEY CLUSTERED ([Id] ASC)
);

CREATE TABLE [dbo].[Computers] (
    [Id]              UNIQUEIDENTIFIER NOT NULL,
    [ComputerName]    NVARCHAR (MAX)   NULL,
    [CredentialId]    UNIQUEIDENTIFIER NOT NULL,
    [OperatingSystem] NVARCHAR (MAX)   NULL,
    [RPC]             BIT              NOT NULL,
    [SMB]             BIT              NOT NULL,
    [SSH]             BIT              NOT NULL,
    [Scanned]         BIT              NOT NULL,
    [WinRM]           BIT              NOT NULL,
    CONSTRAINT [PK_Computers] PRIMARY KEY CLUSTERED ([Id] ASC),
    CONSTRAINT [FK_Computers_Credentials_CredentialId] FOREIGN KEY ([CredentialId]) REFERENCES [dbo].[Credentials] ([Id]) ON DELETE CASCADE
);

GO
CREATE NONCLUSTERED INDEX [IX_Computers_CredentialId]
    ON [dbo].[Computers]([CredentialId] ASC);

CREATE TABLE [dbo].[Scans] (
    [Id]              UNIQUEIDENTIFIER NOT NULL,
    [ComputerId]      UNIQUEIDENTIFIER NOT NULL,
    [StartTime]       DATETIME2 (7)    NOT NULL,
    [Status]          NVARCHAR (MAX)   NULL,
    [StopTime]        DATETIME2 (7)    NOT NULL,
    [SweepIdentifier] UNIQUEIDENTIFIER DEFAULT ('00000000-0000-0000-0000-000000000000') NOT NULL,
    CONSTRAINT [PK_Scans] PRIMARY KEY CLUSTERED ([Id] ASC),
    CONSTRAINT [FK_Scans_Computers_ComputerId] FOREIGN KEY ([ComputerId]) REFERENCES [dbo].[Computers] ([Id]) ON DELETE CASCADE
);

CREATE TABLE [dbo].[Scripts] (
    [Id]             UNIQUEIDENTIFIER NOT NULL,
    [CreationTime]   DATETIME2 (7)    NOT NULL,
    [Language]       NVARCHAR (MAX)   NOT NULL,
    [LastUpdateTime] DATETIME2 (7)    NOT NULL,
    [Name]           NVARCHAR (MAX)   NOT NULL,
    [Uri]            NVARCHAR (MAX)   NOT NULL,
    [RoutingKey]     NVARCHAR (MAX)   NOT NULL,
    CONSTRAINT [PK_Scripts] PRIMARY KEY CLUSTERED ([Id] ASC)
);

CREATE TABLE [dbo].[Downloads] (
    [Id]           UNIQUEIDENTIFIER NOT NULL,
    [ComputerName] NVARCHAR (MAX)   NOT NULL,
    [Content]      VARBINARY (MAX)  NOT NULL,
    [DownloadTime] DATETIME2 (7)    NOT NULL,
    [FullPath]     NVARCHAR (MAX)   NOT NULL,
    [Name]         NVARCHAR (MAX)   NOT NULL,
    CONSTRAINT [PK_Downloads] PRIMARY KEY CLUSTERED ([Id] ASC)
);

CREATE TABLE [dbo].[Schedules] (
    [Id]             UNIQUEIDENTIFIER NOT NULL,
    [ExecutionCount] INT              NOT NULL,
    [StartTime]      DATETIME2 (7)    NOT NULL,
    [JobName]        NVARCHAR (MAX)   NULL,
    [TriggerName]    NVARCHAR (MAX)   NULL,
    [ScriptId]       NVARCHAR (MAX)   NULL,
    [RepeatCount]    INT              DEFAULT ((0)) NOT NULL,
    CONSTRAINT [PK_Schedules] PRIMARY KEY CLUSTERED ([Id] ASC)
);

CREATE TABLE [dbo].[Sweeps] (
    [Id]            UNIQUEIDENTIFIER NOT NULL,
    [CompleteCount] INT              NOT NULL,
    [EndTime]       DATETIME2 (7)    NOT NULL,
    [ScanCount]     INT              NOT NULL,
    [StartTime]     DATETIME2 (7)    NOT NULL,
    [Status]        NVARCHAR (MAX)   NULL,
    [ErrorCount]    INT              DEFAULT ((0)) NOT NULL,
    CONSTRAINT [PK_Sweeps] PRIMARY KEY CLUSTERED ([Id] ASC)
);

CREATE TABLE [dbo].[Users] (
    [Id]        UNIQUEIDENTIFIER NOT NULL,
    [ApiKey]    NVARCHAR (MAX)   NOT NULL,
    [FirstName] NVARCHAR (MAX)   NULL,
    [IsAdmin]   BIT              NOT NULL,
    [LastName]  NVARCHAR (MAX)   NULL,
    [UserName]  NVARCHAR (MAX)   NOT NULL,
    CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED ([Id] ASC)
);

INSERT 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')

================================================
FILE: ACE-Docker/ace-sql/import-data.sh
================================================
/opt/mssql/bin/sqlservr > /dev/null &

#wait for the SQL Server to come up
sleep 45s


# Check if the database already exists
/opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P $SA_PASSWORD -d ACEWebService -Q "SELECT * FROM dbo.Scripts" >> /dev/null 2>&1
ERROR=$?

if [ $ERROR -ne 0 ]; then
  # Create Unique API Key
  apikey=$(cat /proc/sys/kernel/random/uuid)
  sed -i -e 's/\[APIKEY\]/'"$apikey"'/g' /usr/src/ace/ace.sql

  #run the setup script to create the DB and the schema in the DB
  /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P $SA_PASSWORD -Q "CREATE DATABASE ACEWebService" > /dev/null
  /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P $SA_PASSWORD -d ACEWebService -i /usr/src/ace/ace.sql > /dev/null
else
  # We need to return the ApiKey
  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}')"
fi

echo "\"ApiKey\": \"$apikey\","
echo "\"SQLPassword\": \"$SA_PASSWORD\""
#echo "\"DefaultConnection\": \"Server=sql.ace.local;Database=ACEWebService;User Id=sa;Password=$SA_PASSWORD;MultipleActiveResultSets=true\""

while true; do
sleep 300
done

================================================
FILE: ACE-Docker/ace.env
================================================
SA_PASSWORD=P@ssw0rd!
MSSQL_PID=Standard
RABBITMQ_DEFAULT_USER=ace
RABBITMQ_DEFAULT_PASS=P@ssw0rd!
APIKEY=YOURAPIKEYHERE
WEBSERVICE_IP=192.168.1.10

================================================
FILE: ACE-Docker/docker-compose.yml
================================================
version: '2.1'
networks:
  ace:
    driver: bridge
    ipam:
      config:
        - subnet: 172.18.0.0/16
services:
  ace-rabbitmq:
    image: specterops/ace-rabbitmq
    container_name: ace-rabbitmq
    env_file: ./ace.env
    hostname: ace-rabbitmq
    networks:
      ace:
        ipv4_address: 172.18.0.2
        aliases:
          - rabbitmq.ace.local
    ports: 
      - 5672:5672
      - 15672:15672
  ace-sql:
    image: specterops/ace-sql
    container_name: ace-sql
    env_file: ./ace.env
    hostname: ace-sql
    networks:
      ace:
        aliases:
          - sql.ace.local
        ipv4_address: 172.18.0.3
    ports: 
      - 1433:1433
  ace-nginx:
    image: specterops/ace-nginx
    container_name: ace-nginx
    env_file: ./ace.env
    hostname: ace-nginx
    networks:
      ace:
        aliases:
          - nginx.ace.local
        ipv4_address: 172.18.0.4
    ports:
      - "80:80"
      - "443:443"

================================================
FILE: ACE-Docker/settings.sh
================================================
clear

get_host_ip(){
    # *********** Getting Host IP ***************
    # https://github.com/Invoke-IR/ACE/blob/master/ACE-Docker/start.sh
    echo "[ACE-INSTALLATION-INFO] Obtaining current host IP.."
    unameOut="$(uname -s)"
    case "${unameOut}" in
        Linux*)     host_ip=$(ip route get 1 | awk '{print $NF;exit}');;
        Darwin*)    host_ip=$(ifconfig en0 | grep inet | grep -v inet6 | cut -d ' ' -f2);;
        *)          host_ip="UNKNOWN:${unameOut}"
    esac
}

# Write appsettings.Production.json to screen
get_appsettings_data(){
  echo ""
  echo ""
  echo "=========================================================="
  echo ""
  echo "    \"RabbitMQServer\": \"${host_ip}\""
  echo "    $(docker logs ace-rabbitmq | grep UserName)"
  echo "    $(docker logs ace-rabbitmq | grep Password)"
  echo "    $(docker logs ace-nginx | grep Thumbprint)"
  echo "    \"SQLServer\": \"${host_ip}\""
  echo "    $(docker logs ace-sql | grep SQLPassword)"
  echo ""
  echo "=========================================================="
  echo ""
  echo ""
}

get_ps_settings(){
# Provide configuration details for PowerShell Module
  echo ""
  echo ""
  echo "==============================================================="
  echo "|        Thank you for provisioning ACE with Docker!!         |"
  echo "|  Please use the following information to interact with ACE  |"
  echo "==============================================================="
  echo "" 
  echo "  \$settings = @{"
  echo "    Uri        = 'https://${host_ip}'"
  IFS='"' read -r -a array <<< "$(docker logs ace-sql | grep Api)"
  echo "    ApiKey     = '${array[3]}'"
  IFS='"' read -r -a array <<< "$(docker logs ace-nginx | grep Thumbprint)"
  echo "    Thumbprint = '${array[3]}'"
  echo "  }"
  echo ""
  echo "=============================================================="
  echo ""
  echo ""
}

get_host_ip
get_appsettings_data
get_ps_settings


================================================
FILE: ACE-Docker/start.sh
================================================
# Get directory of script and change to it
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd $DIR

# *********** Check if user is root ***************
if [[ $EUID -ne 0 ]]; then
   echo "[ACE-INSTALLATION-INFO] YOU MUST BE ROOT TO RUN THIS SCRIPT!!!" 
   exit 1
fi

LOGFILE="/var/log/ace-install.log"
echoerror() {
    printf "${RC} * ERROR${EC}: $@\n" 1>&2;
}

# *********** Check System Kernel Name ***************
systemKernel="$(uname -s)"

install_docker(){
  if [ "${systemKernel}" == "Linux" ]; then
      # Reference: https://get.docker.com/
      echo "[ACE-DOCKER-INSTALLATION-INFO] ACE identified Linux as the system kernel"
      echo "[ACE-DOCKER-INSTALLATION-INFO] Checking distribution list and version"
      # *********** Check distribution list ***************
      lsb_dist="$(. /etc/os-release && echo "$ID")"
      lsb_dist="$(echo "$lsb_dist" | tr '[:upper:]' '[:lower:]')"

      # *********** Check distribution version ***************
      case "$lsb_dist" in
          ubuntu)
              if [ -x "$(command -v lsb_release)" ]; then
                  dist_version="$(lsb_release --codename | cut -f2)"
              fi
              if [ -z "$dist_version" ] && [ -r /etc/lsb-release ]; then
                  dist_version="$(. /etc/lsb-release && echo "$DISTRIB_CODENAME")"
              fi
          ;;
          debian|raspbian)
              dist_version="$(sed 's/\/.*//' /etc/debian_version | sed 's/\..*//')"
              case "$dist_version" in
                  9)
                      dist_version="stretch"
                  ;;
                  8)
                      dist_version="jessie"
                  ;;
                  7)
                      dist_version="wheezy"
                  ;;
              esac
          ;;
          centos)
              if [ -z "$dist_version" ] && [ -r /etc/os-release ]; then
                  dist_version="$(. /etc/os-release && echo "$VERSION_ID")"
              fi
          ;;
          rhel|ol|sles)
              ee_notice "$lsb_dist"
              #exit 1
              ;;
          *)
              if [ -x "$(command -v lsb_release)"]; then
                  dist_version="$(lsb_release --release | cut -f2)"
              fi
              if [ -z "$dist_version" ] && [ -r /etc/os-release ]; then
                  dist_version="$(. /etc/os-release && echo "$VERSION_ID")"
              fi
          ;;
      esac
      echo "[ACE-DOCKER-INSTALLATION-INFO] You're using $lsb_dist version $dist_version"            
      ERROR=$?
      if [ $ERROR -ne 0 ]; then
          echoerror "Could not verify distribution or version of the OS (Error Code: $ERROR)."
      fi

      # *********** Check if docker is installed ***************
      if [ -x "$(command -v docker)" ]; then
          echo "[ACE-DOCKER-INSTALLATION-INFO] Docker already installed"
          echo "[ACE-DOCKER-INSTALLATION-INFO] Dockerizing ACE.."
      else
          echo "[ACE-DOCKER-INSTALLATION-INFO] Docker is not installed"
          echo "[ACE-DOCKER-INSTALLATION-INFO] Checking if curl is installed first"
          if [ -x "$(command -v curl)" ]; then
              echo "[ACE-DOCKER-INSTALLATION-INFO] curl is already installed"
              echo "[ACE-DOCKER-INSTALLATION-INFO] Ready to install  Docker.."
          else
              echo "[ACE-DOCKER-INSTALLATION-INFO] curl is not installed"
              echo "[ACE-DOCKER-INSTALLATION-INFO] Installing curl before installing docker.."
              apt-get install -y curl >> $LOGFILE 2>&1
              ERROR=$?
              if [ $ERROR -ne 0 ]; then
                  echoerror "Could not install curl (Error Code: $ERROR)."
                  #exit 1
              fi
          fi
          # ****** Installing via convenience script ***********
          echo "[ACE-DOCKER-INSTALLATION-INFO] Installing docker via convenience script.."
          curl -fsSL get.docker.com -o /tmp/get-docker.sh >> $LOGFILE 2>&1
          chmod +x /tmp/get-docker.sh >> $LOGFILE 2>&1
          /tmp/get-docker.sh >> $LOGFILE 2>&1
          ERROR=$?
          if [ $ERROR -ne 0 ]; then
              echoerror "Could not install docker via convenience script (Error Code: $ERROR)."
              #exit 1
          fi
          # ****** Installing docker-compose ***********
          echo "[ACE-DOCKER-INSTALLATION-INFO] Installing docker-compose .."
          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
          chmod +x /usr/local/bin/docker-compose >> $LOGFILE 2>&1
          ERROR=$?
          if [ $ERROR -ne 0 ]; then
              echoerror "Could not install docker-compose (Error Code: $ERROR)."
              exit 1
          fi
      fi
  else
      # *********** Check if docker is installed ***************
      if [ -x "$(command -v docker)" ]; then
          echo "[ACE-DOCKER-INSTALLATION-INFO] Docker already installed"
          echo "[ACE-DOCKER-INSTALLATION-INFO] Dockerizing ACE.."
      else
          echo "[ACE-DOCKER-INSTALLATION-INFO] Install docker for $systemKernel"
          #exit 1
      fi
  fi
}

get_host_ip(){
    # *********** Getting Host IP ***************
    # https://github.com/Invoke-IR/ACE/blob/master/ACE-Docker/start.sh
    echo "[ACE-INSTALLATION-INFO] Obtaining current host IP.."
    unameOut="$(uname -s)"
    case "${unameOut}" in
        Linux*)     host_ip=$(ip route get 1 | awk '{print $NF;exit}');;
        Darwin*)    host_ip=$(ifconfig en0 | grep inet | grep -v inet6 | cut -d ' ' -f2);;
        *)          host_ip="UNKNOWN:${unameOut}"
    esac
    
    # *********** Accepting Defaults or Allowing user to set ACE IP ***************
    local ip_choice
    local read_input
    read -t 30 -p "[ACE-INSTALLATION-INFO] Set ACE IP. Default value is your current IP: " -e -i ${host_ip} ip_choice
    read_input=$?
    ip_choice="${ip_choice:-$host_ip}"
    if [ $ip_choice != $host_ip ]; then
        host_ip=$ip_choice
    fi
    if [ $read_input  = 142 ]; then
       echo -e "\n[ACE-INSTALLATION-INFO] ACE IP set to ${host_ip}" 
    else
    echo "[ACE-INSTALLATION-INFO] ACE IP set to ${host_ip}"
    fi
}

# Write appsettings.Production.json to screen
get_appsettings_data(){
  echo ""
  echo ""
  echo "=========================================================="
  echo ""
  echo "    \"RabbitMQServer\": \"${host_ip}\""
  echo "    $(docker logs ace-rabbitmq | grep UserName)"
  echo "    $(docker logs ace-rabbitmq | grep Password)"
  echo "    $(docker logs ace-nginx | grep Thumbprint)"
  echo "    \"SQLServer\": \"${host_ip}\""
  echo "    $(docker logs ace-sql | grep SQLPassword)"
  echo ""
  echo "=========================================================="
  echo ""
  echo ""
}

get_ps_settings(){
# Provide configuration details for PowerShell Module
  echo ""
  echo ""
  echo "==============================================================="
  echo "|        Thank you for provisioning ACE with Docker!!         |"
  echo "|  Please use the following information to interact with ACE  |"
  echo "==============================================================="
  echo "" 
  echo "  \$settings = @{"
  echo "    Uri        = 'https://${host_ip}'"
  IFS='"' read -r -a array <<< "$(docker logs ace-sql | grep Api)"
  echo "    ApiKey     = '${array[3]}'"
  IFS='"' read -r -a array <<< "$(docker logs ace-nginx | grep Thumbprint)"
  echo "    Thumbprint = '${array[3]}'"
  echo "  }"
  echo ""
  echo "=============================================================="
  echo ""
  echo ""
}

# Test if Docker and Docker-Compose are installed
install_docker

# Get the IP Address for later
get_host_ip

# Build Docker Images and Start Containers
echo "[ACE-INSTALLATION-INFO] Building ACE Docker Containers"
docker-compose build >> $LOGFILE 2>&1
echo "[ACE-INSTALLATION-INFO] Starting ACE Docker Images"
docker-compose up -d >> $LOGFILE 2>&1

echo "[ACE-INSTALLATION-INFO] Waiting for Docker Images to Start"
sleep 60

get_appsettings_data
get_ps_settings

================================================
FILE: ACE-Management/PS-ACE/Cmdlets/Download-AceFile.ps1
================================================
function Download-AceFile
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory)]
        [string]
        $Uri,

        [Parameter(Mandatory)]
        [string]
        $ApiKey,

        [Parameter(Mandatory)]
        [string]
        $Thumbprint,

        [Parameter(Mandatory)]
        [Guid]
        $ComputerId,

        [Parameter(Mandatory)]
        [string]
        $FilePath
    )

    $body = @{
        Uri = $Uri
        ComputerId = $ComputerId
        FilePath = $FilePath
    }

    try 
    {
        $result = Invoke-AceWebRequest -Method Post -Uri "$($Uri)/ace/download" -Body (ConvertTo-Json $body -Compress) -ContentType application/json -ApiKey $ApiKey -Thumbprint $Thumbprint
        Write-Output ($result | ConvertFrom-Json)        
    }
    catch 
    {
       Write-Warning "test" 
    }
}

================================================
FILE: ACE-Management/PS-ACE/Cmdlets/Get-AceComputer.ps1
================================================
function Get-AceComputer
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory)]
        [string]
        $Uri,

        [Parameter(Mandatory)]
        [string]
        $ApiKey,

        [Parameter(Mandatory)]
        [string]
        $Thumbprint,

        [Parameter()]
        [Guid]
        $Id
    )

    if ($PSBoundParameters.ContainsKey('Id'))
    {
        $Url = "$($Uri)/ace/computer/$($Id)"
    }
    else
    {
        $Url = "$($Uri)/ace/computer"
    }
    
    try
    {
        $result = Invoke-AceWebRequest -Method Get -Uri $Url -ApiKey $ApiKey -Thumbprint $Thumbprint -ErrorAction Stop
        Write-Output ($result | ConvertFrom-Json)
    }
    catch
    {

    }   
}

================================================
FILE: ACE-Management/PS-ACE/Cmdlets/Get-AceCredential.ps1
================================================
function Get-AceCredential
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory)]
        [string]
        $Uri,
        
        [Parameter(Mandatory)]
        [string]
        $ApiKey,

        [Parameter(Mandatory)]
        [string]
        $Thumbprint,

        [Parameter()]
        [Guid]
        $Id
    )
    
    try
    {
        if($PSBoundParameters.ContainsKey('Id'))
        {
            $result = Invoke-AceWebRequest -Method Get -Uri "$($Uri)/ace/credential/pscredential/$($Id)" -ApiKey $ApiKey -Thumbprint $Thumbprint -ErrorAction Stop
            $result = $result | ConvertFrom-Json
            $secpassword = ConvertTo-SecureString -String $result.password -AsPlainText -Force
            $cred = New-Object -TypeName System.Management.Automation.PSCredential($result.userName, $secpassword)
            Write-Output $cred
        }
        else
        {
            $result = Invoke-AceWebRequest -Method Get -Uri "$($Uri)/ace/credential" -ApiKey $ApiKey -Thumbprint $Thumbprint -ErrorAction Stop
            Write-Output ($result | ConvertFrom-Json)
        }
    }
    catch
    {
        
    }
}

================================================
FILE: ACE-Management/PS-ACE/Cmdlets/Get-AceSchedule.ps1
================================================
function Get-AceSchedule
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory)]
        [string]
        $Uri,

        [Parameter(Mandatory)]
        [string]
        $ApiKey,

        [Parameter(Mandatory)]
        [string]
        $Thumbprint        
    )

    try
    {
        $result = Invoke-AceWebRequest -Method Get -Uri "$($Uri)/ace/schedule" -ApiKey $ApiKey -Thumbprint $Thumbprint -ErrorAction Stop
        Write-Output ($result | ConvertFrom-Json)        
    }
    catch
    {
        
    }
}

================================================
FILE: ACE-Management/PS-ACE/Cmdlets/Get-AceScript.ps1
================================================
function Get-AceScript
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory)]
        [string]
        $Uri,

        [Parameter(Mandatory)]
        [string]
        $ApiKey,

        [Parameter(Mandatory)]
        [string]
        $Thumbprint        
    )

    try
    {
        $result = Invoke-AceWebRequest -Method Get -Uri "$($Uri)/ace/script" -ApiKey $ApiKey -Thumbprint $Thumbprint -ErrorAction Stop
        Write-Output ($result | ConvertFrom-Json)        
    }
    catch
    {
        
    }
}

================================================
FILE: ACE-Management/PS-ACE/Cmdlets/Get-AceSweep.ps1
================================================
function Get-AceSweep
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory)]
        [string]
        $Uri,

        [Parameter(Mandatory)]
        [string]
        $ApiKey,

        [Parameter(Mandatory)]
        [string]
        $Thumbprint,

        [Parameter()]
        [Guid]
        $Id
    )

    if ($PSBoundParameters.ContainsKey('Id'))
    {
        $Url = "$($Uri)/ace/sweep/$($Id)"
    }
    else
    {
        $Url = "$($Uri)/ace/sweep"
    }

    try
    {
        $result = Invoke-AceWebRequest -Method Get -Uri $Url -ApiKey $ApiKey -Thumbprint $Thumbprint -ErrorAction Stop
        Write-Output ($result | ConvertFrom-Json)        
    }
    catch
    {
        
    }
}

================================================
FILE: ACE-Management/PS-ACE/Cmdlets/Get-AceSweepResult.ps1
================================================
function Get-AceSweepResult
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory)]
        [string]
        $Uri,

        [Parameter(Mandatory)]
        [string]
        $ApiKey,

        [Parameter(Mandatory)]
        [string]
        $Thumbprint,

        [Parameter()]
        [Guid]
        $Id
    )

    try
    {
        $result = Invoke-AceWebRequest -Method Get -Uri "$($Uri)/ace/scan/$($Id)" -ApiKey $ApiKey -Thumbprint $Thumbprint -ErrorAction Stop
        Write-Output ($result | ConvertFrom-Json)        
    }
    catch
    {
        
    }
}

================================================
FILE: ACE-Management/PS-ACE/Cmdlets/Get-AceUser.ps1
================================================
function Get-AceUser
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory)]
        [string]
        $Uri,

        [Parameter(Mandatory)]
        [string]
        $ApiKey,

        [Parameter(Mandatory)]
        [string]
        $Thumbprint        
    )

    try
    {
        $result = Invoke-AceWebRequest -Method Get -Uri "$($Uri)/ace/user" -ApiKey $ApiKey -Thumbprint $Thumbprint -ErrorAction Stop
        Write-Output ($result | ConvertFrom-Json)        
    }
    catch
    {
        
    }
}

================================================
FILE: ACE-Management/PS-ACE/Cmdlets/Invoke-AceWebRequest.ps1
================================================
function Invoke-AceWebRequest
{
    param
    (
        [Parameter(Mandatory = $true)]
        [string]
        $Uri,

        [Parameter(Mandatory = $true)]
        [string]
        $ApiKey,

        [Parameter(Mandatory)]
        [string]
        $Thumbprint,

        [Parameter()]
        [ValidateSet('Delete','Get','Post','Put')]
        [string]
        $Method = 'Get',

        [Parameter()]
        [string]
        $ContentType = 'application/json',

        [Parameter()]
        [string]
        $Body
    )
    
    try
    {
        # Create web request
        $WebRequest = [System.Net.WebRequest]::Create($Uri)
    
        $WebRequest.Headers.Add('X-API-Version:1.0')
        $webrequest.Headers.Add("X-ApiKey:$($ApiKey)")

        $WebRequest.Method = $Method
        $WebRequest.ContentType = $ContentType

        # Set the callback to check for null certificate and thumbprint matching.
        $WebRequest.ServerCertificateValidationCallback = {
            
            $certificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]$args[1]
            
            if ($certificate -eq $null)
            {
                $Host.UI.WriteWarningLine("Null certificate.")
                return $true
            }
    
            if ($certificate.Thumbprint -eq $Thumbprint)
            {
                return $true
            }
            else
            {
                $Host.UI.WriteWarningLine("Thumbprint mismatch. Certificate thumbprint $($certificate.Thumbprint)")
                $Host.UI.WriteWarningLine("   Expected thumbprint: $($Thumbprint)")
                $Host.UI.WriteWarningLine("   Received thumbprint: $($certificate.Thumbprint)")
            }
    
            return $false
        }

        if($PSBoundParameters.ContainsKey('Body'))
        {
            $byteArray = [System.Text.Encoding]::UTF8.GetBytes($Body)
            $Webrequest.ContentLength = $byteArray.Length
            
            $dataStream = $Webrequest.GetRequestStream()            
            $dataStream.Write($byteArray, 0, $byteArray.Length)
            $dataStream.Close()
        }

        # Get response stream
        $ResponseStream = $webrequest.GetResponse().GetResponseStream()
    
        # Create a stream reader and read the stream returning the string value.
        $StreamReader = New-Object System.IO.StreamReader -ArgumentList $ResponseStream
        $StreamReader.ReadToEnd()

        $StreamReader.Close()
        $ResponseStream.Close()
    }
    catch
    {
        Write-Error "Failed: $($_.exception.innerexception.message)"
    }
}

================================================
FILE: ACE-Management/PS-ACE/Cmdlets/New-AceCredential.ps1
================================================
function New-AceCredential
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory)]
        [string]
        $Uri,

        [Parameter(Mandatory)]
        [string]
        $ApiKey,

        [Parameter(Mandatory)]
        [string]
        $Thumbprint,        

        [Parameter(Mandatory)]
        [Management.Automation.PSCredential]
        [Management.Automation.CredentialAttribute()]
        $Credential
    )

    $body = @{
        UserName = $Credential.UserName
        Password = $Credential.GetNetworkCredential().Password
    }

    try 
    {
        $result = Invoke-AceWebRequest -Method Post -Uri "$($Uri)/ace/credential" -Body (ConvertTo-Json $body -Compress) -ContentType application/json -ApiKey $ApiKey -Thumbprint $Thumbprint
        Write-Output ($result | ConvertFrom-Json)    
    }
    catch 
    {
        
    }
}

================================================
FILE: ACE-Management/PS-ACE/Cmdlets/New-AceScheduledScan.ps1
================================================
function New-AceScheduledScan
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory)]
        [string[]]
        $ComputerId,

        [Parameter(Mandatory)]
        [string]
        $ScriptId,

        [Parameter(Mandatory)]
        [string]
        $Uri,
        
        [Parameter(Mandatory)]
        [string]
        $ApiKey,

        [Parameter(Mandatory)]
        [string]
        $Thumbprint,

        [Parameter(Mandatory)]
        [Int32]
        $Hour,

        [Parameter(Mandatory)]
        [Int32]
        $Minute,

        [Parameter(Mandatory)]
        [Int32]
        $IntervalInMinutes,

        [Parameter()]
        [Int32]
        $RepeatCount = 0
    )

    $body = @{
        ComputerId = $ComputerId
        ScriptId = $ScriptId
        Uri = $Uri
        Hour = $Hour
        Minute = 0
        Interval = $IntervalInMinutes
        RepeatCount = $RepeatCount
    }

    $result = Invoke-AceWebRequest -Method Post -Uri "$($Uri)/ace/schedule" -Body (ConvertTo-Json $body -Compress) -ContentType application/json -ApiKey $ApiKey -Thumbprint $Thumbprint
    Write-Output ($result | ConvertFrom-Json)        
}

================================================
FILE: ACE-Management/PS-ACE/Cmdlets/New-AceScript.ps1
================================================
function New-AceScript
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory)]
        [string]
        $Uri,

        [Parameter(Mandatory)]
        [string]
        $ApiKey,

        [Parameter(Mandatory)]
        [string]
        $Thumbprint,

        [Parameter(Mandatory)]
        [string]
        $Path,

        [Parameter(Mandatory)]
        [string]
        $Name,

        [Parameter(Mandatory)]
        [string]
        $Language,
        
        [Parameter()]
        [string]
        $RoutingKey
    )

    $body = @{
        Name = $Name
        Language = $Language
        RoutingKey = $RoutingKey
        Content = [System.IO.File]::ReadAllBytes($Path)
    }

    try 
    {
        $result = Invoke-AceWebRequest -Method Post -Uri "$($Uri)/ace/script" -Body (ConvertTo-Json $body -Compress) -ContentType application/json -ApiKey $ApiKey -Thumbprint $Thumbprint
        Write-Output ($result | ConvertFrom-Json)        
    }
    catch 
    {
        
    }
}

================================================
FILE: ACE-Management/PS-ACE/Cmdlets/New-AceUser.ps1
================================================
function New-AceUser
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory)]
        [string]
        $Uri,

        [Parameter(Mandatory)]
        [string]
        $ApiKey,

        [Parameter(Mandatory)]
        [string]
        $Thumbprint,

        [Parameter(Mandatory)]
        [string]
        $UserName,
        
        [Parameter()]
        [string]
        $FirstName = $null,

        [Parameter()]
        [string]
        $LastName = $null,

        [Parameter()]
        [bool]
        $IsAdmin = $false
    )

    $body = @{
        UserName = $UserName
        FirstName = $FirstName
        LastName = $LastName
        IsAdmin = $IsAdmin
    }

    try 
    {
        $result = Invoke-AceWebRequest -Method Post -Uri "$($Uri)/ace/user" -Body (ConvertTo-Json $body -Compress) -ContentType application/json -ApiKey $ApiKey -Thumbprint $Thumbprint
        Write-Output ($result | ConvertFrom-Json)        
    }
    catch 
    {
        
    }
}

================================================
FILE: ACE-Management/PS-ACE/Cmdlets/Remove-AceCredential.ps1
================================================
function Remove-AceCredential
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory)]
        [string]
        $Uri,

        [Parameter(Mandatory)]
        [string]
        $ApiKey,

        [Parameter(Mandatory)]
        [string]
        $Thumbprint,

        [Parameter(Mandatory)]
        [Guid]
        $Id
    )

    try
    {
        $result = Invoke-AceWebRequest -Method Get -Uri "$($Uri)/ace/credential/delete/$($Id)" -ApiKey $ApiKey -Thumbprint $Thumbprint
        Write-Output ($result | ConvertFrom-Json)   
    }
    catch
    {
        
    }
}

================================================
FILE: ACE-Management/PS-ACE/Cmdlets/Remove-AceScript.ps1
================================================
function Remove-AceScript
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory)]
        [string]
        $Uri,

        [Parameter(Mandatory)]
        [string]
        $ApiKey,

        [Parameter(Mandatory)]
        [string]
        $Thumbprint,

        [Parameter(Mandatory)]
        [Guid]
        $Id
    )

    try
    {
        $result = Invoke-AceWebRequest -Method Get -Uri "$($Uri)/ace/script/delete/$($Id)" -ApiKey $ApiKey -Thumbprint $Thumbprint
        Write-Output ($result | ConvertFrom-Json)   
    }
    catch
    {
        
    }
}

================================================
FILE: ACE-Management/PS-ACE/Cmdlets/Remove-AceUser.ps1
================================================
function Remove-AceUser
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory)]
        [string]
        $Uri,

        [Parameter(Mandatory)]
        [string]
        $ApiKey,

        [Parameter(Mandatory)]
        [string]
        $Thumbprint,

        [Parameter(Mandatory)]
        [Guid]
        $Id
    )

    try
    {
        $result = Invoke-AceWebRequest -Method Get -Uri "$($Uri)/ace/user/delete/$($Id)" -ApiKey $ApiKey -Thumbprint $Thumbprint
        Write-Output ($result | ConvertFrom-Json)   
    }
    catch
    {
        
    }
}

================================================
FILE: ACE-Management/PS-ACE/Cmdlets/Send-AceResult.ps1
================================================
function Send-AceResult
{
    <#
    .SYNOPSIS
    Short description
    
    .DESCRIPTION
    Long description
    
    .EXAMPLE
    An example
    
    .NOTES
    General notes

    #>

    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory = $true, ValueFromPipeline = $true)]
        [psobject[]]
        $InputObject,
        
        [Parameter(Mandatory)]
        [string]
        $Uri
    )

    begin
    {
        $header = @{
            'X-API-Version' = '1.0'
        }
    }

    process
    {
        foreach($o in $InputObject)
        {
            $result = Invoke-WebRequest -Method Post -Uri "$($Uri)/ace/result/e989000d-2b98-44bd-94fc-403c41f42bf5" -Body (ConvertTo-Json $o) -Headers $header -ContentType application/json

            Write-Output ($result.Content | ConvertFrom-Json)
        }
    }

    end
    {

    }
}

================================================
FILE: ACE-Management/PS-ACE/Cmdlets/Start-AceDiscovery.ps1
================================================
function Start-AceDiscovery
{
    [CmdletBinding(DefaultParameterSetName = "Domain")]
    param
    (
        [Parameter(Mandatory)]
        [string]
        $Uri,

        [Parameter(Mandatory)]
        [string]
        $ApiKey,
        
        [Parameter(Mandatory)]
        [string]
        $Thumbprint,

        [Parameter(Mandatory)]
        [Guid]
        $CredentialId,

        [Parameter(Mandatory, ParameterSetName = "Domain")]
        [string]
        $Domain,

        [Parameter(Mandatory, ParameterSetName = "ComputerList")]
        [string[]]
        $ComputerName
    )

    switch($PSCmdlet.ParameterSetName)
    {
        ComputerList
        {
            $body = @{
                ComputerName = $ComputerName
                CredentialId = $CredentialId
            }
            
            $result = Invoke-AceWebRequest -Method Post -Uri "$($Uri)/ace/discover/computerlist" -Body (ConvertTo-Json $body -Compress) -ContentType application/json -ApiKey $ApiKey -Thumbprint $Thumbprint
        }
        Domain
        {
            $body = @{
                Domain = $Domain
                CredentialId = $CredentialId
            }

            $result = Invoke-AceWebRequest -Method Post -Uri "$($Uri)/ace/discover/domain" -Body (ConvertTo-Json $body -Compress) -ContentType application/json -ApiKey $ApiKey -CheckCert
        }
    }

    Write-Output ($result | ConvertFrom-Json)
}

================================================
FILE: ACE-Management/PS-ACE/Cmdlets/Start-AceSweep.ps1
================================================
function Start-AceSweep
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory)]
        [string]
        $Uri,

        [Parameter()]
        [string]
        $ExternalUri,

        [Parameter(Mandatory)]
        [string]
        $ApiKey,

        [Parameter(Mandatory)]
        [string]
        $Thumbprint,

        [Parameter(Mandatory)]
        [Guid[]]
        $ComputerId,

        [Parameter(Mandatory)]
        [Guid]
        $ScriptId      
    )

    if(-not $PSBoundParameters.ContainsKey('ExternalUri'))
    {
        $ExternalUri = $Uri
    }

    $body = @{
        ComputerId = $ComputerId
        ScriptId = $ScriptId
        Uri = $Uri
        ExternalUri = $ExternalUri
    }

    try
    {
        $result = Invoke-AceWebRequest -Method Post -Uri "$($Uri)/ace/sweep" -Body (ConvertTo-Json $body -Compress) -ContentType application/json -ApiKey $ApiKey -Thumbprint $Thumbprint
        Write-Output ($result | ConvertFrom-Json)   
    }
    catch
    {
        
    }
}

================================================
FILE: ACE-Management/PS-ACE/Cmdlets/Update-AceCredential.ps1
================================================
function Update-AceCredential
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory)]
        [string]
        $Uri,

        [Parameter(Mandatory)]
        [string]
        $ApiKey,

        [Parameter(Mandatory)]
        [string]
        $Thumbprint,
        
        [Parameter(Mandatory)]
        [Guid]
        $CredentialId,

        [Parameter(Mandatory)]
        [Management.Automation.PSCredential]
        [Management.Automation.CredentialAttribute()]
        $Credential
    )

    $body = @{
        UserName = $Credential.UserName
        Password = $Credential.GetNetworkCredential().Password
    }

    $result = Invoke-AceWebRequest -Method Put -Uri "$($Uri)/ace/credential/$($CredentialId)" -Body (ConvertTo-Json $body) -ContentType application/json -ApiKey $ApiKey -Thumbprint $Thumbprint

    Write-Output ($result.Content | ConvertFrom-Json)
}

================================================
FILE: ACE-Management/PS-ACE/Cmdlets/Update-AceUser.ps1
================================================
function Update-AceUser
{
    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory)]
        [string]
        $Uri,

        [Parameter(Mandatory)]
        [string]
        $ApiKey,

        [Parameter(Mandatory)]
        [string]
        $Thumbprint,

        [Parameter(Mandatory)]
        [string]
        $UserId,

        [Parameter(Mandatory)]
        [string]
        $UserName,
        
        [Parameter()]
        [string]
        $FirstName = $null,

        [Parameter()]
        [string]
        $LastName = $null,

        [Parameter()]
        [bool]
        $IsAdmin = $false
    )
    
    $body = @{
        UserName = $UserName
        FirstName = $FirstName
        LastName = $LastName
        IsAdmin = $IsAdmin
    }

    $result = Invoke-AceWebRequest -Method Put -Uri "$($Uri)/ace/user/$($UserId)" -Body (ConvertTo-Json $body -Compress) -ContentType application/json -ApiKey $ApiKey -Thumbprint $Thumbprint
    Write-Output ($result | ConvertFrom-Json)
}

================================================
FILE: ACE-Management/PS-ACE/PS-ACE.psm1
================================================
Get-ChildItem "$($PSScriptRoot)\Cmdlets\*" -Include '*.ps1' |
    ForEach-Object {. $_.FullName}

================================================
FILE: ACE-Management/PS-ACE/README.md
================================================
# PS-ACE
The ACE Web Application provides a RESTful API for managment and sweep tasking. PS-ACE is a PowerShell module that interacts with this API.

The 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:
* Web Server URI
* Builtin Administrator's API Key
* Web Server's SSL Certificate Thumbprint

Below is an example of the output from start.sh:
```
==========================================================
|      Thank you for provisioning ACE with Docker!!      |
==========================================================

Please use the following information to interact with ACE:
             Uri: https://10.57.106.141
          ApiKey: 9C8DC642-268D-41EA-9521-43F718119FB7
      Thumbprint: FA4608B93B017DF46D1BC6155DC4C5AF7D83EA1D

==========================================================
```

The 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 '$'.

Below 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**:

```powershell
# Create a hash table with ACE's common parameters
PS> $props = @{
    Uri = 'https://192.168.50.187'
    ApiKey = 'd0bf91fa-9934-40ca-8cb9-5a1168546abc'
    Thumbprint = '39F459D8CBE1D92396A435F6D5B375AED42CE518'
}

# Pass parameters through Splatting the props variable
PS> Get-AceUser @props

id        : 334d89c9-da7a-43e8-a648-5dc8b22019ed
userName  : admin
firstName : Admin
lastName  : Admin
isAdmin   : True
apiKey    : 9C8DC642-268D-41EA-9521-43F718119FB7
```

## Cmdlets
### Get-AceComputer
### Get-AceCredential
### Get-AceSchedule
### Get-AceScript
### Get-AceSweep
### Get-AceSweepResult
### Get-AceUser
### Invoke-AceWebRequest
### New-AceCredential
### New-AceScheduledScan
### New-AceScript
### New-AceUser
### Remove-AceCredential
### Remove-AceScript
### Remove-AceUser
### Send-AceResult
### Start-AceDiscovery
### Start-AceSweep
### Update-AceCredential
### Update-AceUser

================================================
FILE: ACE-Management/PS-ACE/Scripts/ACE-Master.ps1
================================================
function Start-AceScript
{
    param
    (
        [Parameter(Mandatory = $true)]
        [string]
        $Uri,

        [Parameter(Mandatory = $true)]
        [string]
        $SweepId,

        [Parameter(Mandatory = $true)]
        [string]
        $ScanId,

        [Parameter(Mandatory = $true)]
        [string]
        $Thumbprint,

        [Parameter()]
        [ValidateSet('All','AccessToken','ArpCache','AtomTable','FullProcess','FullService','InjectedThread','KerberosTicket','LogonSession','MasterBootRecord','NetworkConnection','RegistryAutoRun','ScheduledTask','SecurityPackage','SimpleNamedPipe','WmiEventSubscription')]
        [string[]]
        $ScanType = 'All'

    )

    $HostFQDN = Get-WmiObject Win32_ComputerSystem -Property 'Name','Domain' | ForEach-Object {"$($_.Name).$($_.Domain)"}
    $ResultDate = (Get-Date).ToString("yyyyMMddThhmmssmsmsZ")

    $scans = New-Object -TypeName System.Collections.Generic.List['Hashtable']
    
    if($ScanType -contains 'All' -or $ScanType -contains 'AccessToken')
    {
        $scans.Add(@{Function = 'Get-AccessToken'; RoutingKey = 'siem'; ScanType = 'AccessToken'})
    }
    if($ScanType -contains 'All' -or $ScanType -contains 'ArpCache')
    {
        $scans.Add(@{Function = 'Get-ArpCache -ReturnHashtables'; RoutingKey = 'siem'; ScanType = 'ArpCache'})
    }
    if($ScanType -contains 'All' -or $ScanType -contains 'AtomTable')
    {
        $scans.Add(@{Function = 'Get-AtomTable -ReturnHashtables'; RoutingKey = 'siem'; ScanType = 'AtomTable'})
    }
    if($ScanType -contains 'All' -or $ScanType -contains 'FullProcess')
    {
        $scans.Add(@{Function = 'Get-PSIProcess -ReturnHashtables'; RoutingKey = 'hash.siem'; ScanType = 'FullProcess'})
    }    
    if($ScanType -contains 'All' -or $ScanType -contains 'FullService')
    {
        $scans.Add(@{Function = 'Get-PSIService -ReturnHashtables'; RoutingKey = 'siem'; ScanType = 'FullService'})
    }
    if($ScanType -contains 'All' -or $ScanType -contains 'InjectedThread')
    {    
        $scans.Add(@{Function = 'Get-InjectedThread'; RoutingKey = 'siem'; ScanType = 'InjectedThread'})
    }
    if($ScanType -contains 'All' -or $ScanType -contains 'KerberosTicket')
    {
        $scans.Add(@{Function = 'Get-KerberosTicketCache'; RoutingKey = 'siem'; ScanType = 'KerberosTicket'})
    }
    if($ScanType -contains 'All' -or $ScanType -contains 'LogonSession')
    {
        $scans.Add(@{Function = 'Get-LogonSession -ReturnHashtables'; RoutingKey = 'siem'; ScanType = 'LogonSession'})
    }
    if($ScanType -contains 'All' -or $ScanType -contains 'MasterBootRecord')
    {
        $scans.Add(@{Function = 'Get-MasterBootRecord -ReturnHashtables'; RoutingKey = 'siem'; ScanType = 'MasterBootRecord'})
    }
    if($ScanType -contains 'All' -or $ScanType -contains 'NetworkConnection')
    {
        $scans.Add(@{Function = 'Get-NetworkConnection -ReturnHashtables'; RoutingKey = 'siem'; ScanType = 'NetworkConnection'})
    }
    if($ScanType -contains 'All' -or $ScanType -contains 'RegistryAutoRun')
    {
        $scans.Add(@{Function = 'Get-RegistryAutoRun'; RoutingKey = 'siem'; ScanType = 'RegistryAutoRun'})
    }
    if($ScanType -contains 'All' -or $ScanType -contains 'ScheduledTask')
    {    
        $scans.Add(@{Function = 'Get-PSIScheduledTask -ReturnHashtables'; RoutingKey = 'siem'; ScanType = 'ScheduledTask'})
    }
    if($ScanType -contains 'All' -or $ScanType -contains 'SecurityPackage')
    {
        $scans.Add(@{Function = 'Get-SecurityPackage -ReturnHashtables'; RoutingKey = 'siem'; ScanType = 'SecurityPackage'})
    }
    if($ScanType -contains 'All' -or $ScanType -contains 'SimpleNamedPipe')
    {
        $scans.Add(@{Function = 'Get-SimpleNamedPipe -ReturnHashtables'; RoutingKey = 'siem'; ScanType = 'SimpleNamedPipe'})
    }
    if($ScanType -contains 'All' -or $ScanType -contains 'WmiEventSubscription')
    {
        $scans.Add(@{Function = 'Get-WmiEventSubscription -ReturnHashtables'; RoutingKey = 'siem'; ScanType = 'WmiEventSubscription'})
    }

    foreach($scan in $scans)
    {
        $dataList = New-Object -TypeName System.Collections.Generic.List['string']

        Write-Host -NoNewline -ForegroundColor Yellow -Object '[!] '
        Write-Host "[$($HostFQDN)] $($scan.ScanType)"

        foreach($o in (Invoke-Expression $scan.Function))
        {
            $o.Add('ComputerName', $HostFQDN)
            $o.Add('ScanType', $scan.ScanType)
            $o.Add('SweepId', $SweepId)
            $o.Add('ScanId', $ScanId)
            $o.Add('ResultDate', $ResultDate)

            $message = ConvertTo-JsonV2 -InputObject $o
            $dataList.Add($message)
        }

        $props = @{
            ComputerName = $HostFQDN
            ScanType     = $scan.ScanType
            RoutingKey   = $scan.RoutingKey
            ResultDate   = $ResultDate
            ScanId       = $ScanId
            Data         = $dataList.ToArray()
        }

        $body = (ConvertTo-JsonV2 -InputObject $props)
        
        #Write-Output $body
        Invoke-AceWebRequest -Thumbprint $Thumbprint -Uri "$($Uri)/ace/result/$($SweepId)" -Body $body
    }
}

function ConvertTo-JsonV2 
{
    param
    (
        [Parameter(Mandatory = $true)]
        $InputObject
    )

    Begin 
    {
        $null = [System.Reflection.Assembly]::LoadWithPartialName("System.Web.Extensions")
        $Serializer = New-Object System.Web.Script.Serialization.JavaScriptSerializer
    }

    Process 
    {
        try 
        {
            $Serializer.Serialize($InputObject)
        } 
        catch 
        {
            Write-Error $_
        }    
    }
}

function Invoke-AceWebRequest
{
    param
    (
        [Parameter(Mandatory = $true)]
        [string]
        $Thumbprint,

        [Parameter(Mandatory = $true)]
        [string]
        $Uri,

        [Parameter(Mandatory = $true)]
        [string]
        $Body
    )

    [Net.ServicePointManager]::ServerCertificateValidationCallback = {
        $Thumbprint = $Thumbprint
        $certificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]$args[1]
    
        if ($certificate -eq $null)
        {
            $Host.UI.WriteErrorLine("Null certificate.")
            return $true
        }
    
        if ($certificate.Thumbprint -eq $Thumbprint)
        {
            return $true
        }
        else
        {
            $Host.UI.WriteErrorLine("Thumbprint mismatch. Certificate thumbprint $($certificate.Thumbprint)")
        }
    
        return $false
    }

    try
    {
        #Write-Host "URI: $($Uri)"

        # Create web request
        $WebRequest = [Net.WebRequest]::Create($uri)
        $WebRequest.Method = 'Post'
        $WebRequest.ContentType = 'application/json'
        $WebRequest.Headers.Add('X-API-Version:1.0')

        $byteArray = [System.Text.Encoding]::UTF8.GetBytes($Body)
        $Webrequest.ContentLength = $byteArray.Length
        
        $dataStream = $Webrequest.GetRequestStream()            
        $dataStream.Write($byteArray, 0, $byteArray.Length)
        $dataStream.Close()

        # Get response stream
        $ResponseStream = $Webrequest.GetResponse().GetResponseStream()
    
        # Create a stream reader and read the stream returning the string value.
        $StreamReader = New-Object System.IO.StreamReader -ArgumentList $ResponseStream
        $StreamReader.ReadToEnd()
    }
    catch
    {
        Write-Error "Failed: $($_.exception.innerexception.message)"
    }
}

#region Collection Functions
function Get-AccessToken
{
    param
    (
        [Parameter()]
        [System.Diagnostics.Process[]]
        $Process
    )

    begin
    {
        <#
        try
        {
            Get-System
        }
        catch
        {
            Write-Error "Unable to Impersonate NT AUTHORITY\SYSTEM token"
        }
        #>

        if(-not ($PSBoundParameters.ContainsKey('Process')))
        {
            $Process = Get-Process
        }
    }

    process
    {
        foreach($proc in $Process)
        {
            if($proc.Id -ne 0 -and $proc.Id -ne 4 -and $proc.Id -ne $PID)
            {
                $ProcessGuid = [Guid]::NewGuid()

                try
                {
                    $hProcess = OpenProcess -ProcessId $proc.Id -DesiredAccess PROCESS_QUERY_LIMITED_INFORMATION
                }
                catch
                {
                    if($_.Exception.Message -ne "OpenProcess Error: The parameter is incorrect")
                    {
                        Write-Warning "Process Handle: $($proc.Id)"
                        Write-Warning $_.Exception.Message
                    }
                }

                try
                {
                    $hToken = OpenProcessToken -ProcessHandle $hProcess -DesiredAccess TOKEN_QUERY
                }
                catch
                {
                    #Write-Warning "Process Token Handle: $($proc.Id)"
                    #Write-Warning $_.Exception.Message
                }

                try
                {
                    $TokenUser = GetTokenInformation -TokenInformationClass TokenUser -TokenHandle $hToken
                    $TokenGroup = GetTokenInformation -TokenInformationClass TokenGroups -TokenHandle $hToken
                    $TokenOwner = GetTokenInformation -TokenInformationClass TokenOwner -TokenHandle $hToken
                    $TokenIntegrityLevel = GetTokenInformation -TokenInformationClass TokenIntegrityLevel -TokenHandle $hToken
                    $TokenType = GetTokenInformation -TokenInformationClass TokenType -TokenHandle $hToken
                    $TokenSessionId = GetTokenInformation -TokenInformationClass TokenSessionId -TokenHandle $hToken
                    $TokenOrigin = GetTokenInformation -TokenInformationClass TokenOrigin -TokenHandle $hToken
                    $TokenPrivileges = (GetTokenInformation -TokenInformationClass TokenPrivileges -TokenHandle $hToken | Where-Object {$_.Attributes -like "*ENABLED*"} | select -ExpandProperty Privilege) -join ";"
                    $TokenElevation = GetTokenInformation -TokenInformationClass TokenElevation -TokenHandle $hToken
                    $TokenElevationType = GetTokenInformation -TokenInformationClass TokenElevationType -TokenHandle $hToken

                    $props = @{
                        ProcessGuid = $ProcessGuid
                        ProcessName = $proc.Name
                        ProcessId = $proc.Id
                        ThreadId = 0
                        UserSid = $TokenUser.Sid.ToString()
                        UserName = $TokenUser.Name.Value
                        OwnerSid = $TokenOwner.Sid.ToString()
                        OwnerName = $TokenOwner.Name.Value
                        #Groups = $TokenGroup
                        IntegrityLevel = $TokenIntegrityLevel.ToString()
                        Type = $TokenType.ToString()
                        ImpersonationLevel = 'None'
                        SessionId = $TokenSessionId -as ([Int32])
                        Origin = $TokenOrigin -as ([Int32])
                        Privileges = $TokenPrivileges
                        IsElevated = $TokenElevation -as ([bool])
                        ElevationType = $TokenElevationType.ToString()
                    }

                    Write-Output $props

                    CloseHandle -Handle $hProcess
                    CloseHandle -Handle $hToken
                }
                catch
                {
                    #Write-Warning "Process Token Query: $($proc.Id)"
                    #Write-Warning $_.Exception.Message
                }

                foreach($thread in $proc.Threads)
                {
                    try
                    {
                        $hThread = OpenThread -ThreadId $thread.Id -DesiredAccess THREAD_QUERY_LIMITED_INFORMATION

                        try
                        {
                            $hToken = OpenThreadToken -ThreadHandle $hThread -DesiredAccess TOKEN_QUERY

                            $TokenUser = GetTokenInformation -TokenInformationClass TokenUser -TokenHandle $hToken
                            $TokenGroup = GetTokenInformation -TokenInformationClass TokenGroups -TokenHandle $hToken
                            $TokenOwner = GetTokenInformation -TokenInformationClass TokenOwner -TokenHandle $hToken
                            $TokenIntegrityLevel = GetTokenInformation -TokenInformationClass TokenIntegrityLevel -TokenHandle $hToken
                            $TokenType = GetTokenInformation -TokenInformationClass TokenType -TokenHandle $hToken
                            if($TokenType -eq 'TokenImpersonation')
                            {
                                $TokenImpersonationLevel = GetTokenInformation -TokenInformationClass TokenImpersonationLevel -TokenHandle $hToken
                            }
                            else
                            {
                                $TokenImpersonationLevel = 'None'
                            }
                            $TokenSessionId = GetTokenInformation -TokenInformationClass TokenSessionId -TokenHandle $hToken
                            $TokenOrigin = GetTokenInformation -TokenInformationClass TokenOrigin -TokenHandle $hToken
                            $TokenPrivileges = (GetTokenInformation -TokenInformationClass TokenPrivileges -TokenHandle $hToken | Where-Object {$_.Attributes -like "*ENABLED*"} | select -ExpandProperty Privilege) -join ";"
                            $TokenElevation = GetTokenInformation -TokenInformationClass TokenElevation -TokenHandle $hToken
                            $TokenElevationType = GetTokenInformation -TokenInformationClass TokenElevationType -TokenHandle $hToken
                        
                            $props = @{
                                ProcessGuid = $ProcessGuid
                                ProcessName = $proc.Name
                                ProcessId = $proc.Id
                                ThreadId = $thread.Id
                                UserSid = $TokenUser.Sid.ToString()
                                UserName = $TokenUser.Name.Value
                                OwnerSid = $TokenOwner.Sid.ToString()
                                OwnerName = $TokenOwner.Name.Value
                                #Groups = $TokenGroup
                                IntegrityLevel = $TokenIntegrityLevel.ToString()
                                Type = $TokenType.ToString()
                                ImpersonationLevel = $TokenImpersonationLevel.ToString()
                                SessionId = $TokenSessionId -as ([Int32])
                                Origin = $TokenOrigin -as ([Int32])
                                Privileges = $TokenPrivileges
                                IsElevated = $TokenElevation -as ([bool])
                                ElevationType = $TokenElevationType.ToString()
                            }

                            Write-Output $props    

                            CloseHandle -Handle $hThread
                            CloseHandle -Handle $hToken
                        }
                        catch
                        {
                            if($_.Exception.Message -ne 'OpenThreadToken Error: An attempt was made to reference a token that does not exist')
                            {
                                #Write-Warning "Thread Token Handle"
                                #Write-Warning $_.Exception.Message
                            }
                        }
                    }
                    catch
                    {
                        #Write-Warning "Thread Handle: [Proc] $($proc.Id) [THREAD] $($thread.Id)"
                        #Write-Warning $_.Exception.Message
                    }
                }
            }
        }
    }

    end
    {
        RevertToSelf
    }
}

function Get-ArpCache
{
    <#
    .SYNOPSIS

    Gets the contents of the ARP Cache.

    .DESCRIPTION
    
    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).

    .NOTES

    Author: Jared Atkinson (@jaredcatkinson)
    License: BSD 3-Clause
    Required Dependencies: None
    Optional Dependencies: None

    .EXAMPLE

    Get-ArpCache

    AdapterIndex       : 1
    PhysicalAddress    : 00-00-00-00-00-00
    IpAddress          : 224.0.0.22
    Type               : STATIC
    AdapterServiceName : e1iexpress
    AdapterMacAddress  : 00:0C:29:3A:DF:39
    AdapterType        : Ethernet 802.3
    AdapterName        : Intel(R) 82574L Gigabit Network Connection
    AdapterSpeed       : 1000000000

    AdapterIndex       : 1
    PhysicalAddress    : 00-00-00-00-00-00
    IpAddress          : 224.0.0.252
    Type               : STATIC
    AdapterServiceName : e1iexpress
    AdapterMacAddress  : 00:0C:29:3A:DF:39
    AdapterType        : Ethernet 802.3
    AdapterName        : Intel(R) 82574L Gigabit Network Connection
    AdapterSpeed       : 1000000000

    AdapterIndex       : 1
    PhysicalAddress    : 00-00-00-00-00-00
    IpAddress          : 239.255.255.250
    Type               : STATIC
    AdapterServiceName : e1iexpress
    AdapterMacAddress  : 00:0C:29:3A:DF:39
    AdapterType        : Ethernet 802.3
    AdapterName        : Intel(R) 82574L Gigabit Network Connection
    AdapterSpeed       : 1000000000
    #>

    param
    (
        [Parameter()]
        [switch]
        $ReturnHashtables
    )

    $Entries = GetIpNetTable
    
    foreach($Entry in $Entries)
    {
        $Adapter = Get-WmiObject -Class win32_networkadapter -Filter "DeviceID = $($Entry.AdapterIndex)"
        
        $Entry.Add('AdapterServiceName', $Adapter.ServiceName)
        $Entry.Add('AdapterMacAddress', $Adapter.MACAddress)
        $Entry.Add('AdapterType', $Adapter.AdapterType)
        $Entry.Add('AdapterName', $Adapter.Name)
        $Entry.Add('AdapterSpeed', $Adapter.Speed)
        
        if($ReturnHashtables)
        {
            Write-Output $Entry
        }
        else
        {
            New-Object -TypeName psobject -Property $Entry
        }
    }
}

function Get-AtomTable
{
    [CmdletBinding()]
    param
    (
        [Parameter()]
        [UInt16]
        $AtomIndex,

        [Parameter()]
        [switch]
        $ReturnHashtables
    )

    if($PSBoundParameters.ContainsKey('AtomIndex'))
    {
        GlobalGetAtomName -AtomIndex $AtomIndex
    }
    else
    {
        $atomList = New-Object -TypeName System.Collections.Generic.List['string']

        for($i = 0xC000; $i -lt [UInt16]::MaxValue; $i++)
        {
            try
            {
                $atomname = GlobalGetAtomName -AtomIndex $i -ErrorAction Stop
            
                $props = @{
                    Index = $i
                    Name = $atomname.ToString()
                }

                if($ReturnHashtables)
                {
                    Write-Output $props
                }
                else
                {
                    New-Object -TypeName psobject -Property $props
                }
            }
            catch
            {

            }
        }
    }
}

function Get-InjectedThread
{
    <# 
    
    .SYNOPSIS 
    
    Looks for threads that were created as a result of code injection.
    
    .DESCRIPTION
    
    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.
    
    Common memory injection techniques that *can* be caught using this method include:
    - Classic Injection (OpenProcess, VirtualAllocEx, WriteProcessMemory, CreateRemoteThread)
    - Reflective DLL Injection
    - Process Hollowing

    NOTE: Nothing in security is a silver bullet. An attacker could modify their tactics to avoid detection using this methodology.
    
    .NOTES

    Author - Jared Atkinson (@jaredcatkinson)

    .EXAMPLE 
    
    PS > Get-InjectedThread 

    ProcessName               : ThreadStart.exe
    ProcessId                 : 7784
    Path                      : C:\Users\tester\Desktop\ThreadStart.exe
    KernelPath                : C:\Users\tester\Desktop\ThreadStart.exe
    CommandLine               : "C:\Users\tester\Desktop\ThreadStart.exe"
    PathMismatch              : False
    ThreadId                  : 14512
    AllocatedMemoryProtection : PAGE_EXECUTE_READWRITE
    MemoryProtection          : PAGE_EXECUTE_READWRITE
    MemoryState               : MEM_COMMIT
    MemoryType                : MEM_PRIVATE
    BasePriority              : 8
    IsUniqueThreadToken       : False
    Integrity                 : MEDIUM_MANDATORY_LEVEL
    Privilege                 : SeChangeNotifyPrivilege
    LogonId                   : 999
    SecurityIdentifier        : S-1-5-21-386661145-2656271985-3844047388-1001
    UserName                  : DESKTOP-HMTGQ0R\SYSTEM
    LogonSessionStartTime     : 3/15/2017 5:45:38 PM
    LogonType                 : System
    AuthenticationPackage     : NTLM
    BaseAddress               : 4390912
    Size                      : 4096
    Bytes                     : {144, 195, 0, 0...}
    
    #>

    [CmdletBinding()]
    param
    (

    )

    $hSnapshot = CreateToolhelp32Snapshot -ProcessId 0 -Flags 4

    $Thread = Thread32First -SnapshotHandle $hSnapshot
    
    do
    {
        $proc = Get-Process -Id $Thread.th32OwnerProcessId -ErrorAction SilentlyContinue
        
        if($Thread.th32OwnerProcessId -ne 0 -and $Thread.th32OwnerProcessId -ne 4)
        {       
            try
            {
                $hThread = OpenThread -ThreadId $Thread.th32ThreadID -DesiredAccess THREAD_QUERY_INFORMATION
            
                if($hThread -ne 0)
                {
                    $BaseAddress = NtQueryInformationThread -ThreadHandle $hThread -ThreadInformationClass ThreadQuerySetWin32StartAddress
                    $hProcess = OpenProcess -ProcessId $Thread.th32OwnerProcessID -DesiredAccess PROCESS_QUERY_LIMITED_INFORMATION -InheritHandle $false
                
                    if($hProcess -ne 0)
                    {
                        $memory_basic_info = VirtualQueryEx -ProcessHandle $hProcess -BaseAddress $BaseAddress
                        $AllocatedMemoryProtection = $memory_basic_info.AllocationProtect -as $MEMORY_PROTECTION
                        $MemoryProtection = $memory_basic_info.Protect -as $MEMORY_PROTECTION
                        $MemoryState = $memory_basic_info.State -as $MEMORY_STATE
                        $MemoryType = $memory_basic_info.Type -as $MEMORY_TYPE

                        if($MemoryState -eq $MEMORY_STATE::MEM_COMMIT -and $MemoryType -ne $MEMORY_TYPE::MEM_IMAGE)
                        {   
                            $buf = ReadProcessMemory -ProcessHandle $hProcess -BaseAddress $BaseAddress -Size 100
                            $proc = Get-WmiObject Win32_Process -Filter "ProcessId = '$($Thread.th32OwnerProcessID)'"
                            $KernelPath = QueryFullProcessImageName -ProcessHandle $hProcess
                            $PathMismatch = $proc.Path.ToLower() -ne $KernelPath.ToLower()
                            
                            # check if thread has unique token
                            try
                            {
                                $hThreadToken = OpenThreadToken -ThreadHandle $hThread -DesiredAccess TOKEN_QUERY
                                
                                $TokenUser = GetTokenInformation -TokenInformationClass TokenUser -TokenHandle $hThreadToken
                                $TokenOwner = GetTokenInformation -TokenInformationClass TokenOwner -TokenHandle $hThreadToken
                                $TokenIntegrityLevel = GetTokenInformation -TokenInformationClass TokenIntegrityLevel -TokenHandle $hThreadToken
                                $TokenType = GetTokenInformation -TokenInformationClass TokenType -TokenHandle $hThreadToken
                                if($TokenType -eq 'TokenImpersonation')
                                {
                                    $TokenImpersonationLevel = GetTokenInformation -TokenInformationClass TokenImpersonationLevel -TokenHandle $hThreadToken
                                }
                                else
                                {
                                    $TokenImpersonationLevel = 'None'
                                }
                                $TokenSessionId = GetTokenInformation -TokenInformationClass TokenSessionId -TokenHandle $hThreadToken
                                $TokenOrigin = GetTokenInformation -TokenInformationClass TokenOrigin -TokenHandle $hThreadToken
                                $TokenPrivileges = (GetTokenInformation -TokenInformationClass TokenPrivileges -TokenHandle $hThreadToken | Where-Object {$_.Attributes -like "*ENABLED*"} | select -ExpandProperty Privilege) -join ";"
                                $TokenElevation = GetTokenInformation -TokenInformationClass TokenElevation -TokenHandle $hThreadToken
                                $TokenElevationType = GetTokenInformation -TokenInformationClass TokenElevationType -TokenHandle $hThreadToken
                            }
                            catch
                            {
                                $hProcessToken = OpenProcessToken -ProcessHandle $hProcess -DesiredAccess TOKEN_QUERY
                                
                                $TokenUser = GetTokenInformation -TokenInformationClass TokenUser -TokenHandle $hProcessToken
                                $TokenOwner = GetTokenInformation -TokenInformationClass TokenOwner -TokenHandle $hProcessToken
                                $TokenIntegrityLevel = GetTokenInformation -TokenInformationClass TokenIntegrityLevel -TokenHandle $hProcessToken
                                $TokenType = GetTokenInformation -TokenInformationClass TokenType -TokenHandle $hProcessToken
                                $TokenImpersonationLevel = 'None'
                                $TokenSessionId = GetTokenInformation -TokenInformationClass TokenSessionId -TokenHandle $hProcessToken
                                $TokenOrigin = GetTokenInformation -TokenInformationClass TokenOrigin -TokenHandle $hProcessToken
                                $TokenPrivileges = (GetTokenInformation -TokenInformationClass TokenPrivileges -TokenHandle $hProcessToken | Where-Object {$_.Attributes -like "*ENABLED*"} | select -ExpandProperty Privilege) -join ";"
                                $TokenElevation = GetTokenInformation -TokenInformationClass TokenElevation -TokenHandle $hProcessToken
                                $TokenElevationType = GetTokenInformation -TokenInformationClass TokenElevationType -TokenHandle $hProcessToken
                            }

                            $props = @{
                                ProcessName = [string]$proc.Name
                                ProcessId = $proc.ProcessId
                                Path = [string]$proc.Path
                                KernelPath = [string]$KernelPath
                                CommandLine = [string]$proc.CommandLine
                                PathMismatch = [string]$PathMismatch
                                ThreadId = $Thread.th32ThreadId
                                AllocatedMemoryProtection = [string]$AllocatedMemoryProtection
                                MemoryProtection = [string]$MemoryProtection
                                MemoryState = [string]$MemoryState
                                MemoryType = [string]$MemoryType
                                BasePriority = $Thread.tpBasePri
                                BaseAddress = [string]$BaseAddress
                                Size = $memory_basic_info.RegionSize
                                TokenUserSid = $TokenUser.Sid.ToString()
                                TokenUserName = $TokenUser.Name.Value
                                TokenOwnerSid = $TokenOwner.Sid.ToString()
                                TokenOwnerName = $TokenOwner.Name.Value
                                TokenIntegrity = $TokenIntegrityLevel.ToString()
                                TokenType = $TokenType.ToString()
                                TokenImpersonationLevel = $TokenImpersonationLevel.ToString()
                                TokenSessionId = $TokenSessionId -as ([Int32])
                                TokenOrigin = $TokenOrigin -as ([Int32])
                                TokenPrivilege = $TokenPrivileges
                                TokenElevation = $TokenElevation -as ([bool])
                                TokenElevationType = $TokenElevationType.ToString()
                            }
                        
                            Write-Output $props
                        }
                        CloseHandle($hProcess)
                    }
                }
                CloseHandle($hThread)
            }
            catch
            {

            }
        }
    } while($Kernel32::Thread32Next($hSnapshot, [ref]$Thread))
    CloseHandle($hSnapshot)
}

function Get-KerberosTicketCache
{
    <#
    .SYNOPSIS

    
    .DESCRIPTION


    .NOTES

    Author: Jared Atkinson (@jaredcatkinson)
    License: BSD 3-Clause
    Required Dependencies: None
    Optional Dependencies: None

    .EXAMPLE
    
    #>
    
    [CmdletBinding()]
    param
    (

    )
    
    try
    {
        # We need a Handle to LSA to list Kerberos tickets
        # If we want to look at tickets from a session other than our own
        # Then we need to use LsaRegisterLogonProcess instead of LsaConnectUntrusted
        $hLsa = LsaRegisterLogonProcess
    }
    catch
    {
        # If the original call fails then it is likely we don't have SeTcbPrivilege
        # To get SeTcbPrivilege we can Impersonate a NT AUTHORITY\SYSTEM Token
        Get-System
            
        # We should now have the proper privileges to get a Handle to LSA
        $hLsa = LsaRegisterLogonProcess

        # We don't need our NT AUTHORITY\SYSTEM Token anymore
        # So we can revert to our original token
        RevertToSelf
    }

    # Enumerate all Logon Sessions
    # We need the sessions' LogonIds to enumerate it
    $Sessions = Get-LogonSession

    foreach($Session in $Sessions)
    {
        try
        {
            # Get the tickets from the LSA provider
            $ticket = LsaCallAuthenticationPackage -LsaHandle $hLsa -AuthenticationPackageName MICROSOFT_KERBEROS_NAME_A -LogonId $Session.LogonId 
            
            if($ticket -ne $null)
            {
                # Add properties from the Logon Session to the ticket
                foreach($t in $ticket)
                {
                    $t.Add('SessionLogonId', $Session.LogonId)
                    $t.Add('SessionUserName', $Session.UserName)
                    $t.Add('SessionLogonDomain', $Session.LogonDomain)
                    $t.Add('SessionAuthenticationPackage', $Session.AuthenticationPackage)
                    $t.Add('SessionSid', $Session.Sid.ToString())
                    $t.Add('SessionLogonType', $Session.LogonType)
                    $t.Add('SessionUserPrincipalName', $Session.Upn)
                }


                # Output the ticket
                Write-Output $ticket
            }
        }
        catch
        {

        }
    }

    # Cleanup our LSA Handle
    LsaDeregisterLogonProcess -LsaHandle $hLsa
}

function Get-LogonSession
{
    <#

    .SYNOPSIS

    .DESCRIPTION

    .NOTES

    Author: Jared Atkinson (@jaredcatkinson)
    License: 
    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)
    Optional Dependencies: None

    .LINK

    .EXAMPLE

    Get-LogonSession

    FailedAttemptCountSinceLastSuccessfulLogon : 0
    DnsDomainName                              : HUNT.LOCAL
    KickOffTime                                : 1/1/1601 1:00:00 AM
    PasswordCanChange                          : 5/20/2017 9:51:20 PM
    Upn                                        : Administrator@HUNT.LOCAL
    UserName                                   : Administrator
    Session                                    : 1
    LogoffTime                                 : 1/1/1601 1:00:00 AM
    LastFailedLogon                            : 1/1/1601 1:00:00 AM
    LogonServer                                : DC
    Sid                                        : S-1-5-21-3250051078-751264820-3215766868-500
    LogonScript                                : 
    UserFlags                                  : 49444
    ProfilePath                                : 
    PasswordMustChange                         : 6/30/2017 9:51:20 PM
    LogonId                                    : 325349
    LogonTime                                  : 5/20/2017 9:47:34 AM
    PasswordLastSet                            : 5/19/2017 9:51:20 PM
    LogonDomain                                : 
    HomeDirectory                              : 
    LogonType                                  : Interactive
    AuthenticationPackage                      : Kerberos
    LastSuccessfulLogon                        : 1/1/1601 1:00:00 AM
    HomeDirectoryDrive                         : 

    #>

    [CmdletBinding()]
    param
    (
        [Parameter()]
        [switch]
        $ReturnHashtables
    )

    $LogonSessions = LsaEnumerateLogonSessions

    try
    {
        $Sessions = LsaGetLogonSessionData -LuidPtr $LogonSessions.SessionListPointer -SessionCount $LogonSessions.SessionCount
    }
    catch
    {
        
    }

    if($ReturnHashtables)
    {
        Write-Output $Sessions
    }
    else
    {
        foreach($session in $Sessions)
        {
            New-Object -TypeName psobject -Property $session
        }
    }
}

function Get-MasterBootRecord
{
<#
    .SYNOPSIS

        Returns detailed information about the master boot record

        Author: Jared Atkinson
        License: BSD 3-Clause
        Required Dependencies: None
        Optional Dependencies: None

#>
    [CmdletBinding()]
    Param
    (
        [Parameter()]
        [String[]]
        $Path,

        [switch]
        $ReturnHashtables
    )
    
    begin
    {
        function Get-FileHandle
        {
            [CmdletBinding()]
            param
            (
                [Parameter(Mandatory = $true)]
                [string]
                $Path
            )
            
            #region Constants
        
            $GENERIC_READWRITE = 0x80000000
            $FILE_SHARE_READWRITE = 0x02 -bor 0x01
            $OPEN_EXISTING = 0x03
        
            #endregion

            #region Reflection
            $DynAssembly = New-Object System.Reflection.AssemblyName('Win32')
            $AssemblyBuilder = [AppDomain]::CurrentDomain.DefineDynamicAssembly($DynAssembly, [Reflection.Emit.AssemblyBuilderAccess]::Run)
            $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('Win32', $False)

            $TypeBuilder = $ModuleBuilder.DefineType('Win32.Kernel32', 'Public, Class')
            $DllImportConstructor = [Runtime.InteropServices.DllImportAttribute].GetConstructor(@([String]))
            $SetLastError = [Runtime.InteropServices.DllImportAttribute].GetField('SetLastError')
            $SetLastErrorCustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($DllImportConstructor,
                @('kernel32.dll'),
                [Reflection.FieldInfo[]]@($SetLastError),
                @($True))

            # Define [Win32.Kernel32]::CreateFile
            $PInvokeMethod = $TypeBuilder.DefinePInvokeMethod('CreateFile',
                'kernel32.dll',
                ([Reflection.MethodAttributes]::Public -bor [Reflection.MethodAttributes]::Static),
                [Reflection.CallingConventions]::Standard,
                [Microsoft.Win32.SafeHandles.SafeFileHandle],
                [Type[]]@([String], [Int32], [UInt32], [IntPtr], [UInt32], [UInt32], [IntPtr]),
                [Runtime.InteropServices.CallingConvention]::Winapi,
                [Runtime.InteropServices.CharSet]::Ansi)
            $PInvokeMethod.SetCustomAttribute($SetLastErrorCustomAttribute)

            $Kernel32 = $TypeBuilder.CreateType()
            #endregion

            # Get handle to $FileToServe
            $DriveHandle = $Kernel32::CreateFile($Path, $GENERIC_READWRITE, $FILE_SHARE_READWRITE, 0, $OPEN_EXISTING, 0, 0)

            # Check that handle is valid
            if ($DriveHandle.IsInvalid) {
                Write-Error "Invalid handle to $($Path) returned from CreateFile" -ErrorAction Stop
            }
            else {
                $DriveHandle
            }
        }
               
        function Read-MbrBytes
        {
            [CmdletBinding()]
            param
            (
                [Parameter(Mandatory = $true)]
                [Microsoft.Win32.SafeHandles.SafeFileHandle]
                $Handle
            )

            try
            {
                # Create a FileStream to read from the handle
                $streamToRead = New-Object -TypeName System.IO.FileStream($Handle, [System.IO.FileAccess]::Read)
            
                # Set our position in the stream to $Offset
                $streamToRead.Position = 0x0
        
                # Create a buffer $Length bytes long
                $buffer = New-Object -TypeName Byte[](0x200)

                # Read $Length bytes
                $return = $streamToRead.Read($buffer, 0x0, 0x200)
            
                # Check return value
                if($return -ne 0x200)
                {
                    $return
                }

                $buffer
            }
            catch
            {
                Write-Error "Unable to read bytes from Drive" -ErrorAction Stop
            }
            finally
            {
                $streamToRead.Dispose()
            }
        }
        
        function Get-MD5Hash
        {
            param
            (
                [Parameter(Mandatory = $true)]
                [byte[]]
                $Bytes
            )
            
            begin
            {
                $sha1 = New-Object -TypeName System.Security.Cryptography.MD5CryptoServiceProvider
                $hashbytes = $sha1.ComputeHash($Bytes)
                $sb = New-Object -TypeName System.Text.StringBuilder
            }

            process
            {
                foreach($b in $hashbytes)
                {
                    $null = $sb.Append("{0:x}" -f $b)
                }

                $sb.ToString()
            }

            end
            {
                if($sha1.Dispose) {
                    $sha1.Dispose()
                }
            }
        }

        function Get-Partition
        {
            param
            (
                [Parameter(Mandatory = $true)]
                [byte[]]
                $Bytes,

                [Parameter(Mandatory = $true)]
                [int]
                $Offset,

                [switch]
                $ReturnHashtables
            )

            # Status (0x00 - Non-Bootable & 0x80 - Bootable)
            if($Bytes[0x00 + $Offset] -eq 0x80)
            {
                $Bootable = $true
            }
            else
            {
                $Bootable = $false
            }

            $props = @{
                Bootable = $Bootable
                PartitionType = $Bytes[0x04 + $Offset]
                RelativeStartSector = [System.BitConverter]::ToUInt32($Bytes, 0x08 + $Offset)
                TotalSectors = [System.BitConverter]::ToUInt32($Bytes, 0x0C + $Offset)
            }

            if($ReturnHashtables) {
                $props
            } else {
                New-Object -TypeName psobject -Property $props
            }
        }
    }

    process
    {
        if(-not($PSBoundParameters.ContainsKey('Path')))
        {
            $Disks = Get-WmiObject -Query "SELECT * FROM Win32_DiskDrive"
        }
        else
        {

        }

        $OS = (Get-WmiObject win32_Operatingsystem).Caption

        foreach($disk in $Disks)
        {
            $hDrive = Get-FileHandle -Path $disk.DeviceId

            if($hDrive) {
                $bytes = Read-MbrBytes -Handle $hDrive

                $CodeSection = $bytes[0x3E..0x1B7]

                $listPartitions = New-Object -TypeName System.Collections.Generic.List[HashTable]

                for($i = 0; $i -lt 4; $i++)
                {
                    if($ReturnHashtables) {
                        $partition = Get-Partition -Bytes $bytes -Offset (0x1BE + (0x10 * $i)) -ReturnHashtables
                    } else {
                        $partition = Get-Partition -Bytes $bytes -Offset (0x1BE + (0x10 * $i))
                    }

                    if($partition.TotalSectors -ne 0)
                    {
                        $listPartitions.Add($partition)
                    }
                }

                $Props = @{
                    OperatingSystem = $OS
                    DeviceId = $disk.DeviceId
                    Model = $disk.Model
                    Signature = Get-MD5Hash -Bytes $CodeSection
                    CodeSection = $CodeSection
                    DiskSignature = [System.BitConverter]::ToString($bytes[0x1B8..0x1BB]).Replace("-", "")
                    PartitionTable = $listPartitions.ToArray()
                }

                if($ReturnHashtables) {
                    $Props
                } else {
                    New-Object -TypeName psobject -Property $Props
                }
            }
        }
    }
}

function Get-NetworkConnection 
{
    <#
    .SYNOPSIS

    Returns current TCP and UDP connections.

    .NOTES

    Author: Lee Christensen (@tifkin_)
    License: BSD 3-Clause
    Required Dependencies: None
    Optional Dependencies: None
    #>
    [CmdletBinding()]
    param 
    (
        [switch]
        $ResolveHostnames,

        [switch]
        $ReturnHashtables
    )

    $Tcp4Connections = Get-Tcp4Connections @PSBoundParameters
    $Tcp6Connections = Get-Tcp6Connections @PSBoundParameters
    $Udp4Connections = Get-Udp4Connections @PSBoundParameters
    $Udp6Connections = Get-Udp6Connections @PSBoundParameters

    $Tcp4Connections
    $Tcp6Connections
    $Udp4Connections
    $Udp6Connections
}

function Get-PSIProcess
{
<#
    .SYNOPSIS

        Returns detailed information about the current running processes.

        Author: Lee Christensen (@tifkin_)
        License: BSD 3-Clause
        Required Dependencies: None
        Optional Dependencies: None

#>
    [CmdletBinding()]
    Param (
        [switch]
        $ReturnHashtables
    )

    # TODO: Optimize this cmdlet...

    begin
    {
        # Thanks to https://p0w3rsh3ll.wordpress.com/2015/02/05/backporting-the-get-filehash-function/
        function Get-DIGSFileHash
        {
            [CmdletBinding(DefaultParameterSetName = "Path")]
            param
            (
                [Parameter(Mandatory=$true, ParameterSetName="Path", Position = 0)]
                [System.String[]]
                $Path,

                [Parameter(Mandatory=$true, ParameterSetName="LiteralPath", ValueFromPipelineByPropertyName = $true)]
                [Alias("PSPath")]
                [System.String[]]
                $LiteralPath,
        
                [Parameter(Mandatory=$true, ParameterSetName="Stream")]
                [System.IO.Stream]
                $InputStream,

                [ValidateSet("SHA1", "SHA256", "SHA384", "SHA512", "MACTripleDES", "MD5", "RIPEMD160")]
                [System.String]
                $Algorithm="SHA256"
            )
    
            begin
            {
                # Construct the strongly-typed crypto object
                $hasher = [System.Security.Cryptography.HashAlgorithm]::Create($Algorithm)
            }
    
            process
            {
                if($PSCmdlet.ParameterSetName -eq "Stream")
                {
                    Get-DIGSStreamHash -InputStream $InputStream -RelatedPath $null -Hasher $hasher
                }
                else
                {
                    $pathsToProcess = @()
                    if($PSCmdlet.ParameterSetName  -eq "LiteralPath")
                    {
                        $pathsToProcess += Resolve-Path -LiteralPath $LiteralPath | Foreach-Object { $_.ProviderPath }
                    }
                    if($PSCmdlet.ParameterSetName -eq "Path")
                    {
                        $pathsToProcess += Resolve-Path $Path | Foreach-Object { $_.ProviderPath }
                    }

                    foreach($filePath in $pathsToProcess)
                    {
                        if(Test-Path -LiteralPath $filePath -PathType Container)
                        {
                            continue
                        }

                        try
                        {
                            # Read the file specified in $FilePath as a Byte array
                            [system.io.stream]$stream = [system.io.file]::OpenRead($filePath)
                            Get-DIGSStreamHash -InputStream $stream  -RelatedPath $filePath -Hasher $hasher
                        }
                        catch [Exception]
                        {
                            $errorMessage = 'FileReadError {0}:{1}' -f $FilePath, $_
                            Write-Error -Message $errorMessage -Category ReadError -ErrorId "FileReadError" -TargetObject $FilePath
                            return
                        }
                        finally
                        {
                            if($stream)
                            {
                                $stream.Close()
                            }
                        }                            
                    }
                }
            }
        }

        function Get-DIGSStreamHash
        {
            param
            (
                [System.IO.Stream]
                $InputStream,

                [System.String]
                $RelatedPath,

                [System.Security.Cryptography.HashAlgorithm]
                $Hasher
            )

            # Compute file-hash using the crypto object
            [Byte[]] $computedHash = $Hasher.ComputeHash($InputStream)
            [string] $hash = [BitConverter]::ToString($computedHash) -replace '-',''

            if ($RelatedPath -eq $null)
            {
                $retVal = [PSCustomObject] @{
                    Algorithm = $Algorithm.ToUpperInvariant()
                    Hash = $hash
                }
                $retVal.psobject.TypeNames.Insert(0, "Microsoft.Powershell.Utility.FileHash")
                $retVal
            }
            else
            {
                $retVal = [PSCustomObject] @{
                    Algorithm = $Algorithm.ToUpperInvariant()
                    Hash = $hash
                    Path = $RelatedPath
                }
                $retVal.psobject.TypeNames.Insert(0, "Microsoft.Powershell.Utility.FileHash")
                $retVal

            }
        }
 
        $FileHashCache = @{}
        $Processes = Get-WmiObject -Class Win32_Process

        function Get-DIGSCachedFileHash
        {
            param
            (
                [string]
                $File
            )

            if($FileHashCache[$File])
            {
                $FileHashCache[$File]
            }
            else
            {
                if($File -and (Test-Path $File))
                {
                    $ModuleMD5 = (Get-DIGSFileHash -Path $File -Algorithm MD5).Hash
                    $ModuleSHA256 = (Get-DIGSFileHash -Path $File -Algorithm SHA256).Hash

                    $FileHashCache[$File] = New-Object PSObject -Property @{
                        MD5 = $ModuleMD5
                        SHA256 = $ModuleSHA256
                    }

                    $FileHashCache[$File]
                }
            }
        }
    }

    process
    {
        foreach($Process in $Processes)
        {
            $Proc = Get-Process -Id $Process.ProcessId -ErrorAction SilentlyContinue
            $Path = $Proc.Path
            $LoadedModules = $null
            $Owner = $null
            $OwnerStr = $null

            if($Proc)
            {
                #$PE = Get-PE -ModuleBaseAddress $Proc.MainModule.BaseAddress -ProcessID $Process.ProcessId
                $Proc.Modules | ForEach-Object {
                    if($_) 
                    {
                        $ModuleHash = Get-DIGSCachedFileHash -File $_.FileName

                        $_ | Add-Member NoteProperty -Name "MD5Hash" -Value $ModuleHash.MD5
                        $_ | Add-Member NoteProperty -Name "SHA256Hash" -Value $ModuleHash.SHA256
                    }
                }
                $LoadedModules = $Proc.Modules
            }

            # Get file information
            $FileHash = $null
            if($Path -ne $null -and (Test-Path $Path)) {
                # TODO: Add error handling here in case we can't read the file (wonky exe permissions)

                $FileHash = Get-DIGSCachedFileHash -File $Path

                $File = (Get-ChildItem $Path)
                $FileSize = $File.Length
                $FileCreationTime = $File.CreationTimeUtc
                $FileLastAccessTime = $File.LastAccessTimeUtc
                $FileLastWriteTime = $File.LastWriteTimeUtc
                $FileExtension = $File.Extension
                $ProcessId = $Process.ProcessId
            } else {
                if($Proc.Id -ne 0 -and $Proc.Id -ne 4)
                {
                    #Write-Warning "Could not find executable path. PSProcessName: $($Proc.Name) PSPid: $($Proc.Id) WMIProcName: $($Process.Name) WMIPid: $($Process.ProcessId)"
                }
                $Path = ''
            }
        
            # Get the process owner
            $NTVersion = [System.Environment]::OSVersion.Version
            try {
                if($NTVersion.Major -ge 6)
                {
                    $Owner = $Process.GetOwner()
                    if($Owner -and ($Owner.Domain -or $Owner.User)) {
                        $OwnerStr = "$($Owner.Domain)\$($Owner.User)"
                    }
        
                    $OwnerObj = $Process.GetOwnerSid()
                    if($OwnerObj)
                    {
                        $OwnerSid = $OwnerObj.Sid
                    }
                }
            } catch {}

            $LoadedModuleList = $LoadedModules | sort ModuleName | select -ExpandProperty ModuleName
            $ParentProcess = Get-Process -Id $Process.ProcessId -ErrorAction SilentlyContinue
        
            $ErrorActionPreference = 'Stop'
            $Output = @{
                Name = $Process.Name
                Path = [string]$Process.Path
                CommandLine = $Process.CommandLine
                MD5Hash = $FileHash.MD5
                SHA256Hash = $FileHash.SHA256
                FileSize = $FileSize
                FileCreationTime = $FileCreationTime
                FileLastAccessTime = $FileLastAccessTime
                FileLastWriteTime = $FileLastWriteTime
                FileExtension = $FileExtension
                Owner = $OwnerStr
                OwnerSid = $OwnerSid
                ParentProcessId = $Process.ParentProcessID
                ParentProcessName = $ParentProcess.Name
                ProcessId = $ProcessId
                ## PE = $PE
                #LoadedModules = $LoadedModules | select *
                LoadedModulesList = ($LoadedModuleList -join ";").ToLower()
            }

            try {
                $null = ConvertTo-JsonV2 $Output
            } catch {
                Write-Error $_
            }

            if($ReturnHashtables) {
                $Output
            } else {
                 New-Object PSObject -Property $Output
            }
        }
    }

    end
    {

    }
}

function Get-PSIScheduledTask 
{
<#
    .SYNOPSIS

        Returns detailed information about scheduled tasks.

        Author: Lee Christensen (@tifkin_), Jared Atkinson
        License: BSD 3-Clause
        Required Dependencies: None
        Optional Dependencies: None

#>
    [CmdletBinding()]
    Param (
        [switch]
        $ReturnHashtables
    )

    begin
    {
        # Based on Get-ScheduledTask in the Windows 7 Resource Kit PowerShell Pack
        function Get-DIGSScheduledTaskData
        {
            <#
            .Synopsis
                Gets tasks scheduled on the computer
            .Description
                Gets scheduled tasks that are registered on a computer
            .Example
                Get-ScheduleTask -Recurse
            #>
            param(
            # The name or name pattern of the scheduled task
            [Parameter()]
            $Name = "*",
    
            # The folder the scheduled task is in
            [Parameter()]
            [String[]]
            $Folder = "",
    
            # If this is set, hidden tasks will also be shown.  
            # By default, only tasks that are not marked by Task Scheduler as hidden are shown.
            [Switch]
            $Hidden,    
    
            # The name of the computer to connect to.
            $ComputerName,
    
            # The credential used to connect
            [Management.Automation.PSCredential]
            $Credential,
    
            # If set, will get tasks recursively beneath the specified folder
            [switch]
            $Recurse
            )
    
            process {
                $scheduler = New-Object -ComObject Schedule.Service
                if ($Credential) { 
                    $NetworkCredential = $Credential.GetNetworkCredential()
                    $scheduler.Connect($ComputerName, 
                        $NetworkCredential.UserName, 
                        $NetworkCredential.Domain, 
                        $NetworkCredential.Password)            
                } else {
                    $scheduler.Connect($ComputerName)        
                }    
                
                $taskFolder = $scheduler.GetFolder($folder)
                $taskFolder.GetTasks($Hidden -as [bool]) | Where-Object {
                    $_.Name -like $name
                }
                if ($Recurse) {
                    $taskFolder.GetFolders(0) | ForEach-Object {
                        $psBoundParameters.Folder = $_.Path
                        Get-DIGSScheduledTaskData @psBoundParameters
                    }
                }        
            }
        }

        # Thanks to https://p0w3rsh3ll.wordpress.com/2015/02/05/backporting-the-get-filehash-function/
        function Get-DIGSFileHash
        {
	        [CmdletBinding(DefaultParameterSetName = "Path")]
	        param(
		        [Parameter(Mandatory=$true, ParameterSetName="Path", Position = 0)]
		        [System.String[]]
		        $Path,

		        [Parameter(Mandatory=$true, ParameterSetName="LiteralPath", ValueFromPipelineByPropertyName = $true)]
		        [Alias("PSPath")]
		        [System.String[]]
		        $LiteralPath,
	
		        [Parameter(Mandatory=$true, ParameterSetName="Stream")]
		        [System.IO.Stream]
		        $InputStream,

		        [ValidateSet("SHA1", "SHA256", "SHA384", "SHA512", "MACTripleDES", "MD5", "RIPEMD160")]
		        [System.String]
		        $Algorithm="SHA256"
	        )

	        begin
	        {
		        # Construct the strongly-typed crypto object
		        $hasher = [System.Security.Cryptography.HashAlgorithm]::Create($Algorithm)
	        }

	        process
	        {
		        if($PSCmdlet.ParameterSetName -eq "Stream")
		        {
			        Get-DIGSStreamHash -InputStream $InputStream -RelatedPath $null -Hasher $hasher
		        }
		        else
		        {
			        $pathsToProcess = @()
			        if($PSCmdlet.ParameterSetName  -eq "LiteralPath")
			        {
				        $pathsToProcess += Resolve-Path -LiteralPath $LiteralPath | Foreach-Object { $_.ProviderPath }
			        }
			        if($PSCmdlet.ParameterSetName -eq "Path")
			        {
				        $pathsToProcess += Resolve-Path $Path | Foreach-Object { $_.ProviderPath }
			        }

			        foreach($filePath in $pathsToProcess)
			        {
				        if(Test-Path -LiteralPath $filePath -PathType Container)
				        {
					        continue
				        }

				        try
				        {
					        # Read the file specified in $FilePath as a Byte array
					        [system.io.stream]$stream = [system.io.file]::OpenRead($filePath)
					        Get-DIGSStreamHash -InputStream $stream  -RelatedPath $filePath -Hasher $hasher
				        }
				        catch [Exception]
				        {
					        $errorMessage = 'FileReadError {0}:{1}' -f $FilePath, $_
					        Write-Error -Message $errorMessage -Category ReadError -ErrorId "FileReadError" -TargetObject $FilePath
					        return
				        }
				        finally
				        {
					        if($stream)
					        {
						        $stream.Close()
					        }
				        }                            
			        }
		        }
	        }
        }

        function Get-DIGSStreamHash
        {
	        param(
		        [System.IO.Stream]
		        $InputStream,

		        [System.String]
		        $RelatedPath,

		        [System.Security.Cryptography.HashAlgorithm]
		        $Hasher)

	        # Compute file-hash using the crypto object
	        [Byte[]] $computedHash = $Hasher.ComputeHash($InputStream)
	        [string] $hash = [BitConverter]::ToString($computedHash) -replace '-',''

	        if ($RelatedPath -eq $null)
	        {
		        $retVal = [PSCustomObject] @{
			        Algorithm = $Algorithm.ToUpperInvariant()
			        Hash = $hash
		        }
		        $retVal.psobject.TypeNames.Insert(0, "Microsoft.Powershell.Utility.FileHash")
		        $retVal
	        }
	        else
	        {
		        $retVal = [PSCustomObject] @{
			        Algorithm = $Algorithm.ToUpperInvariant()
			        Hash = $hash
			        Path = $RelatedPath
		        }
		        $retVal.psobject.TypeNames.Insert(0, "Microsoft.Powershell.Utility.FileHash")
		        $retVal

	        }
        }

        function Get-ClassID
        {
            param($ClassId)
  
            $Value = Get-ItemProperty "HKLM:\Software\Classes\CLSID\$($ClassId)\InprocServer32" -Name "(Default)" -ErrorAction SilentlyContinue
            if($Value) {
                $Value.'(Default)'
            } else {
                ''
            }
        }  
    }

    process
    {
        $Tasks = Get-DIGSScheduledTaskData -Recurse

        foreach($Task in $Tasks)
        {
            $ActionComClassId = $null
            $ActionComDll = $null
            $ActionComDllMD5 = $null
            $ActionComDllSHA256 = $null
            $ActionComData = $null
            $ActionExecCommand = $null
            $ActionExecCommandMD5 = $null
            $ActionExecCommandSHA256 = $null
            $ActionExecArguments = $null
            $ActionExecWorkingDirectory = $null
                
            $Xml = [Xml]$Task.Xml
    
            $ActionCom = $Xml.Task.Actions.ComHandler
            $ActionComDll = if($ActionCom.ClassId) { Get-ClassID ($ActionCom.ClassId)} else { $null }
        
            if($ActionComDll)
            {
                $ActionComDllMD5 =  (Get-DIGSFileHash -Path $ActionComDll -Algorithm MD5).Hash
                $ActionComDllSHA256 = (Get-DIGSFileHash -Path $ActionComDll -Algorithm SHA256).Hash
            }
            $ActionComData = if($ActionCom.Data) { $ActionCom.Data.InnerXml} else {$null}

            $ActionExec = $Xml.Task.Actions.Exec
            if($ActionExec.Command)
            {
                $ActionExecPath = [System.Environment]::ExpandEnvironmentVariables($ActionExec.Command)
            
                $CleanedPath = $ActionExecPath.Replace("`"", "")
                if(Test-Path $CleanedPath -ErrorAction SilentlyContinue)
                {
                    $ActionExecCommandMD5 = (Get-DIGSFileHash -Path $CleanedPath -Algorithm MD5).Hash
                    $ActionExecCommandSHA256 = (Get-DIGSFileHash -Path $CleanedPath -Algorithm SHA256).Hash
                }
            }

            $Output = @{
                Name = $Task.Name
                Path = $Task.Path
                Enabled = $Task.Enabled
                LastRunTime = $Task.LastRunTime
                LastTaskResult = $Task.LastTaskResult
                NumberOfMissedRuns = $Task.NumberOfMissedRuns
                NextRunTime = $Task.NextRunTime
                Xml = $Task.Xml
                ActionComClassId = $ActionCom.ClassId
                ActionComDll = $ActionComDll
                ActionComDllMD5 = $ActionComDllMd5
                ActionComDllSHA256 = $ActionComDllSHA256
                ActionComData = $ActionComData
                ActionExecCommand = $ActionExec.Command
                ActionExecCommandMD5 = $ActionExecCommandMD5
                ActionExecCommandSHA256 = $ActionExecCommandSHA256
                ActionExecArguments = $ActionExec.Arguments
                ActionExecWorkingDirectory = $ActionExec.WorkingDirectory
            }

            if($ReturnHashtables) {
                $Output
            } else {
                New-Object PSObject -Property $Output
            }
        }
    }

    end
    {

    }
}

function Get-PSIService 
{
<#
    .SYNOPSIS

        Returns detailed service information.

        Author: Jared Atkinson
        License: BSD 3-Clause
        Required Dependencies: None
        Optional Dependencies: None

#>
    [CmdletBinding()]
    Param (
        [switch]
        $ReturnHashtables
    )

    Begin
    {
        function Get-PathFromCommandLine
        {
            Param
            (
                [Parameter(Mandatory = $true)]
                [string]
                $CommandLine
            )

            if(Test-Path -Path $CommandLine -ErrorAction SilentlyContinue)
            {
                $CommandLine
            }
            else
            {
                switch -Regex ($CommandLine)
                {
                    '"\s'{ $CommandLine.Split('"')[1]; break}
                    '\s-'{ $CommandLine.Split(' ')[0]; break}
                    '\s/'{ $CommandLine.Split(' ')[0]; break}
                    '"'{ $CommandLine.Split('"')[1]; break}
                    default{ $CommandLine}    
                }
            }
        }

        # Thanks to https://p0w3rsh3ll.wordpress.com/2015/02/05/backporting-the-get-filehash-function/
        function Get-DIGSFileHash
        {
            [CmdletBinding(DefaultParameterSetName = "Path")]
            param(
                [Parameter(Mandatory=$true, ParameterSetName="Path", Position = 0)]
                [System.String[]]
                $Path,

                [Parameter(Mandatory=$true, ParameterSetName="LiteralPath", ValueFromPipelineByPropertyName = $true)]
                [Alias("PSPath")]
                [System.String[]]
                $LiteralPath,
        
                [Parameter(Mandatory=$true, ParameterSetName="Stream")]
                [System.IO.Stream]
                $InputStream,

                [ValidateSet("SHA1", "SHA256", "SHA384", "SHA512", "MACTripleDES", "MD5", "RIPEMD160")]
                [System.String]
                $Algorithm="SHA256"
            )
    
            begin
            {
                # Construct the strongly-typed crypto object
                $hasher = [System.Security.Cryptography.HashAlgorithm]::Create($Algorithm)
            }
    
            process
            {
                if($PSCmdlet.ParameterSetName -eq "Stream")
                {
                    Get-DIGSStreamHash -InputStream $InputStream -RelatedPath $null -Hasher $hasher
                }
                else
                {
                    $pathsToProcess = @()
                    if($PSCmdlet.ParameterSetName  -eq "LiteralPath")
                    {
                        $pathsToProcess += Resolve-Path -LiteralPath $LiteralPath | Foreach-Object { $_.ProviderPath }
                    }
                    if($PSCmdlet.ParameterSetName -eq "Path")
                    {
                        $pathsToProcess += Resolve-Path $Path | Foreach-Object { $_.ProviderPath }
                    }

                    foreach($filePath in $pathsToProcess)
                    {
                        if(Test-Path -LiteralPath $filePath -PathType Container)
                        {
                            continue
                        }

                        try
                        {
                            # Read the file specified in $FilePath as a Byte array
                            [system.io.stream]$stream = [system.io.file]::OpenRead($filePath)
                            Get-DIGSStreamHash -InputStream $stream  -RelatedPath $filePath -Hasher $hasher
                        }
                        catch [Exception]
                        {
                            $errorMessage = 'FileReadError {0}:{1}' -f $FilePath, $_
                            Write-Error -Message $errorMessage -Category ReadError -ErrorId "FileReadError" -TargetObject $FilePath
                            return
                        }
                        finally
                        {
                            if($stream)
                            {
                                $stream.Close()
                            }
                        }                            
                    }
                }
            }
        }

        function Get-DIGSStreamHash
        {
            param(
                [System.IO.Stream]
                $InputStream,

                [System.String]
                $RelatedPath,

                [System.Security.Cryptography.HashAlgorithm]
                $Hasher)

            # Compute file-hash using the crypto object
            [Byte[]] $computedHash = $Hasher.ComputeHash($InputStream)
            [string] $hash = [BitConverter]::ToString($computedHash) -replace '-',''

            if ($RelatedPath -eq $null)
            {
                $retVal = [PSCustomObject] @{
                    Algorithm = $Algorithm.ToUpperInvariant()
                    Hash = $hash
                }
                $retVal.psobject.TypeNames.Insert(0, "Microsoft.Powershell.Utility.FileHash")
                $retVal
            }
            else
            {
                $retVal = [PSCustomObject] @{
                    Algorithm = $Algorithm.ToUpperInvariant()
                    Hash = $hash
                    Path = $RelatedPath
                }
                $retVal.psobject.TypeNames.Insert(0, "Microsoft.Powershell.Utility.FileHash")
                $retVal

            }
        }
    
        $hashcache = @{}
        $objList = New-Object -TypeName "System.Collections.Generic.List[Object]"
    }

    Process
    {
        foreach($service in (Get-WmiObject win32_service))
        {
            if($service.PathName -ne $null)
            {
                $path = Get-PathFromCommandLine -CommandLine $service.PathName
            }
            else
            {
                $path = $null
            }

            try
            {
                if($hashcache.ContainsKey($path))
                {
                    $md5 = $hashcache[$path].MD5
                    $sha256 = $hashcache[$path].SHA256
                }
                else
                {
                    $md5 = Get-DIGSFileHash -Path $path -Algorithm MD5 -ErrorAction Stop
                    $sha256 = Get-DIGSFileHash -Path $path -Algorithm SHA256 -ErrorAction Stop
                    $obj = @{
                        MD5 = $md5
                        SHA256 = $sha256
                    }
                    $hashcache.Add($path, $obj)
                }
            }
            catch
            {
                $md5 = $null
                $sha256 = $null
            }
        
            $Props = @{
                Name = $service.Name
                CommandLine = $service.PathName
                ExecutablePath = $path
                ServiceType = $service.ServiceType
                StartMode = $service.StartMode
                Caption = $service.Caption
                Description = $service.Description
                DisplayName = $service.DisplayName
                ProcessId = $service.ProcessId
                Started = $service.Started
                User = $service.StartName
                MD5Hash = $md5.Hash
                SHA256Hash = $sha256.Hash
            }

            if($ReturnHashtables) {
                $Props
            } else {
                New-Object -TypeName psobject -Property $Props
            }
        }
    }

    End
    {

    }
}

function Get-RegistryAutoRun
{
    param
    (
        [Parameter(ParameterSetName = 'SpecificCheck')]
        [Switch]
        $Logon,

        [Parameter(ParameterSetName = 'SpecificCheck')]
        [Switch]
        $BootExecute,

        [Parameter(ParameterSetName = 'SpecificCheck')]
        [Switch]
        $PrintMonitors,

        [Parameter(ParameterSetName = 'SpecificCheck')]
        [Switch]
        $NetworkProviders,

        [Parameter(ParameterSetName = 'SpecificCheck')]
        [Switch]
        $LSAProviders,

        [Parameter(ParameterSetName = 'SpecificCheck')]
        [Switch]
        $ImageHijacks,

        [Parameter(ParameterSetName = 'SpecificCheck')]
        [Switch]
        $AppInit,

        [Parameter(ParameterSetName = 'SpecificCheck')]
        [Switch]
        $KnownDLLs,

        [Parameter(ParameterSetName = 'SpecificCheck')]
        [Switch]
        $Winlogon
    )

    $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

    if (($PSCmdlet.ParameterSetName -ne 'SpecificCheck') -or $PSBoundParameters['Logon'])
    {
        $Category = 'Logon'

        $RunKeyPaths = @(
            'SOFTWARE\Microsoft\Windows\CurrentVersion\Run'
            'SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce'
            'SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Run'
            'SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\RunOnce'
        )

        $KeyList = New-Object -TypeName System.Collections.Generic.List['string']

        foreach ($RunKey in $RunKeyPaths) { $KeyList.Add("HKLM:\$($RunKey)") }
        foreach ($SID in $UserSIDS) { foreach ($RunKey in $RunKeyPaths) { $KeyList.Add("Registry::HKU\$($SID)\$($RunKey)") } }  

        foreach($result in (Get-RegistryValue -Key $KeyList.ToArray()))
        {
            New-AutoRunEntry -Path $result.Path -Name $result.Name -ImagePath $result.Value -Category $Category
        }

        Get-RegistryValue -Key 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server\Wds\rdpwd' -Value StartupPrograms | New-AutoRunEntry -Category $Category
        Get-RegistryValue -Key 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon' -Value VmApplet,Userinit,Shell,TaskMan,AppSetup | New-AutoRunEntry -Category $Category
        Get-RegistryValue -Key 'HKLM:\SYSTEM\CurrentControlSet\Control\SafeBoot' -Value AlternateShell | New-AutoRunEntry -Category $Category
        Get-RegistryValue -Key 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Windows' -Value IconServiceLib | New-AutoRunEntry -Category $Category

        $GPExtensionKey = 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon\GPExtensions'
        Get-ChildItem -Path $GPExtensionKey |
            foreach { Get-RegistryValue -Key "$($GPExtensionKey)\$($_.PSChildName)" -Value DllName | New-AutoRunEntry -Name $_.PSChildName -Category $Category }

        <#
        $null, 'Wow6432Node\' | ForEach-Object {
            $InstalledComponents = "SOFTWARE\$($_)Microsoft\Active Setup\Installed Components"
            Get-RegistryValue -Key "HKLM:\$($InstalledComponents)" -Value StubPath | 
            ForEach-Object {
                $AutoRunEntry = $_ | Get-CSRegistryValue -ValueName '' -ValueType REG_SZ @Timeout
                if ($AutoRunEntry.ValueContent) { $AutoRunEntryName = $AutoRunEntry.ValueContent } else { $AutoRunEntryName = 'n/a' }

                $_ | New-AutoRunsEntry -SubKey $InstalledComponents -AutoRunEntry $AutoRunEntryName -Category $Category
            }
        }
        #>
    }
    
    if (($PSCmdlet.ParameterSetName -ne 'SpecificCheck') -or $PSBoundParameters['BootExecute'])
    {
        $Category = 'BootExecute'

        $SessionManager = 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager'
        foreach ($result in (Get-RegistryValue -Key $SessionManager -Value BootExecute,SetupExecute,Execute,S0InitialCommand))
        {
            foreach ($val in $result.Value)
            {
                New-AutoRunEntry -Path $SessionManager -Name $result.Name -ImagePath $val -Category $Category
            }
        }

        Get-RegistryValue -Key 'HKLM:\SYSTEM\CurrentControlSet\Control' -Value ServiceControlManagerExtension | New-AutoRunEntry -Category $Category
    }

    if (($PSCmdlet.ParameterSetName -ne 'SpecificCheck') -or $PSBoundParameters['PrintMonitors'])
    {
        $Category = 'PrintMonitors'

        Get-RegistryValue -Key 'HKLM:\SYSTEM\CurrentControlSet\Control\Print\Monitors' -Value Driver | New-AutoRunEntry -Category $Category
    }

    if (($PSCmdlet.ParameterSetName -ne 'SpecificCheck') -or $PSBoundParameters['NetworkProviders'])
    {
        $Category = 'NetworkProviders'

        $Path = 'HKLM:\SYSTEM\CurrentControlSet\Control\NetworkProvider\Order'
        $NetworkOrder = Get-RegistryValue -Key $Path -Value ProviderOrder
        
        if ($NetworkOrder.Value)
        {
            foreach($val in ($NetworkOrder.Value.Split(',')))
            {
                New-AutoRunEntry -Path $Path -Name ProviderOrder -ImagePath $val -Category $Category
            }
        }
    }

    if (($PSCmdlet.ParameterSetName -ne 'SpecificCheck') -or $PSBoundParameters['LSAProviders'])
    {
        $Category = 'LSAProviders'

        Get-RegistryValue -Key 'HKLM:\SYSTEM\CurrentControlSet\Control\SecurityProviders' | New-AutoRunEntry -Category $Category
        
        $Path = 'HKLM:\SYSTEM\CurrentControlSet\Control\Lsa'
        foreach($result in (Get-RegistryValue -Key $Path -Value 'Authentication Packages','Notification Packages')) 
        {
            foreach($val in $result.Value)
            {
                New-AutoRunEntry -Path $Path -Name $result.Name -ImagePath $val -Category $Category
            }
        }

        Get-RegistryValue -Key 'HKLM:\SYSTEM\CurrentControlSet\Control\Lsa\OSConfig' -Value 'Security Packages' | New-AutoRunEntry -Category $Category
    }
    
    if (($PSCmdlet.ParameterSetName -ne 'SpecificCheck') -or $PSBoundParameters['ImageHijacks']) {
        $Category = 'ImageHijacks'

        $CommonKeys = @(
            'SOFTWARE\Classes\htmlfile\shell\open\command',
            'SOFTWARE\Classes\htafile\shell\open\command',
            'SOFTWARE\Classes\batfile\shell\open\command',
            'SOFTWARE\Classes\comfile\shell\open\command',
            'SOFTWARE\Classes\piffile\shell\open\command',
            'SOFTWARE\Classes\exefile\shell\open\command'
        )

        foreach ($CommonKey in $CommonKeys) {
            Get-RegistryValue -Key "HKLM:\$($CommonKey)" -Value '' | New-AutoRunsEntry -AutoRunEntry $CommonKey.Split('\')[2] -Category $Category

            # Iterate over each local user hive
            foreach ($SID in $HKUSIDs) {
                Get-CSRegistryValue -Hive HKU -SubKey "$SID\$CommonKey" -ValueName '' @CommonArgs @Timeout |
                    New-AutoRunsEntry -AutoRunEntry $CommonKey.Split('\')[2] -Category $Category
            }
        }

        Get-RegistryValue -Key HKLM:\SOFTWARE\Classes\exefile\shell\open\command -Value IsolatedCommand | New-AutoRunEntry -Category $Category

        <#
        $null, 'Wow6432Node\' | ForEach-Object {
            Get-RegistryValue -Key "HKLM:\SOFTWARE\$($_)Microsoft\Windows NT\CurrentVersion\Image File Execution Options" -Value Debugger | 
                ForEach-Object {
                    $_ | New-AutoRunsEntry -AutoRunEntry $_.SubKey.Substring($_.SubKey.LastIndexOf('\') + 1) -Category $Category
                }

            Get-RegistryValue -Key "HKLM:\SOFTWARE\$($_)Microsoft\Command Processor" -ValueName Autorun | New-AutoRunsEntry -Category $Category
        }

        $Class_exe = Get-CSRegistryValue -Hive HKLM -SubKey 'HKLM:\SOFTWARE\Classes\.exe' -ValueName '' -ValueType REG_SZ @CommonArgs @Timeout

        if ($Class_exe.ValueContent) {
            $OpenCommand = Get-CSRegistryValue -Hive HKLM -SubKey "SOFTWARE\Classes\$($Class_exe.ValueContent)\Shell\Open\Command" -ValueName '' -ValueType REG_SZ @CommonArgs @Timeout

            if ($OpenCommand.ValueContent) {
                $OpenCommand | New-AutoRunsEntry -Hive $Class_exe.Hive -SubKey $Class_exe.SubKey -AutoRunEntry $Class_exe.ValueContent -Category $Category
            }
        }

        $Class_cmd = Get-CSRegistryValue -Hive HKLM -SubKey 'SOFTWARE\Classes\.cmd' -ValueName '' -ValueType REG_SZ @CommonArgs @Timeout

        if ($Class_cmd.ValueContent) {
            $OpenCommand = Get-CSRegistryValue -Hive HKLM -SubKey "SOFTWARE\Classes\$($Class_cmd.ValueContent)\Shell\Open\Command" -ValueName '' -ValueType REG_SZ @CommonArgs @Timeout

            if ($OpenCommand.ValueContent) {
                $OpenCommand | New-AutoRunsEntry -Hive $Class_cmd.Hive -SubKey $Class_cmd.SubKey -AutoRunEntry $Class_cmd.ValueContent -Category $Category
            }
        }

        foreach ($SID in $HKUSIDs) {
            Get-CSRegistryValue -Hive HKU -SubKey "$SID\SOFTWARE\Microsoft\Command Processor" -ValueName 'Autorun' @CommonArgs @Timeout |
                New-AutoRunsEntry -Category $Category

            $Class_exe = Get-CSRegistryValue -Hive HKU -SubKey "$SID\SOFTWARE\Classes\.exe" -ValueName '' -ValueType REG_SZ @CommonArgs @Timeout

            if ($Class_exe.ValueContent) {
                $OpenCommand = Get-CSRegistryValue -Hive HKU -SubKey "$SID\SOFTWARE\Classes\$($Class_exe.ValueContent)\Shell\Open\Command" -ValueName '' -ValueType REG_SZ @CommonArgs @Timeout

                if ($OpenCommand.ValueContent) {
                    $OpenCommand | New-AutoRunsEntry -Hive $Class_exe.Hive -SubKey $Class_exe.SubKey -AutoRunEntry $Class_exe.ValueContent -Category $Category
                }
            }

            $Class_cmd = Get-CSRegistryValue -Hive HKU -SubKey "$SID\SOFTWARE\Classes\.cmd" -ValueName '' -ValueType REG_SZ @CommonArgs @Timeout

            if ($Class_cmd.ValueContent) {
                $OpenCommand = Get-CSRegistryValue -Hive HKU -SubKey "$SID\SOFTWARE\Classes\$($Class_cmd.ValueContent)\Shell\Open\Command" -ValueName '' -ValueType REG_SZ @CommonArgs @Timeout

                if ($OpenCommand.ValueContent) {
                    $OpenCommand | New-AutoRunsEntry -Hive $Class_cmd.Hive -SubKey $Class_cmd.SubKey -AutoRunEntry $Class_cmd.ValueContent -Category $Category
                }
            }
        }
        #>
    }

    if (($PSCmdlet.ParameterSetName -ne 'SpecificCheck') -or $PSBoundParameters['AppInit']) 
    {
        $Category = 'AppInit'

        $null,'Wow6432Node\' | ForEach-Object {
            Get-RegistryValue -Key "HKLM:\SOFTWARE\$($_)Microsoft\Windows NT\CurrentVersion\Windows" -Value 'AppInit_DLLs' | New-AutoRunEntry -Category $Category
            Get-RegistryValue -Key "HKLM:\SOFTWARE\$($_)Microsoft\Command Processor" -Value 'Autorun' | New-AutoRunEntry -Category $Category
        }

        Get-RegistryValue -Key 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\AppCertDlls' | New-AutoRunEntry -Category $Category
    }

    if (($PSCmdlet.ParameterSetName -ne 'SpecificCheck') -or $PSBoundParameters['KnownDLLs']) 
    {
        $Category = 'KnownDLLs'

        Get-RegistryValue -Key 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager\KnownDLLs' | New-AutoRunEntry -Category $Category
    }

    <#
    if (($PSCmdlet.ParameterSetName -ne 'SpecificCheck') -or $PSBoundParameters['Winlogon']) {
        $Category = 'Winlogon'

        $CmdLine = Get-CSRegistryValue -Hive HKLM -SubKey 'SYSTEM\Setup' -ValueName 'CmdLine' @CommonArgs @Timeout

        if ($CmdLine -and $CmdLine.ValueContent) {
            $CmdLine | New-AutoRunsEntry -Category $Category
        }

        'Credential Providers', 'Credential Provider Filters', 'PLAP Providers' |
            ForEach-Object { Get-CSRegistryKey -Hive HKLM -SubKey "SOFTWARE\Microsoft\Windows\CurrentVersion\Authentication\$_" @CommonArgs @Timeout } | ForEach-Object {
                $LastBSIndex = $_.SubKey.LastIndexOf('\')
                $ParentKey = $_.SubKey.Substring(0, $LastBSIndex)
                $Guid = $_.SubKey.Substring($LastBSIndex + 1)

                if ($Guid -as [Guid]) {
                    $AutoRunEntry = Get-CSRegistryValue -Hive HKLM -SubKey "SOFTWARE\Classes\CLSID\$Guid" -ValueName '' -ValueType REG_SZ @CommonArgs @Timeout
                    $InprocServer32 = Get-CSRegistryValue -Hive HKLM -SubKey "SOFTWARE\Classes\CLSID\$Guid\InprocServer32" -ValueName '' -ValueType REG_EXPAND_SZ @CommonArgs @Timeout

                    New-AutoRunsEntry $_.Hive $ParentKey $AutoRunEntry.ValueContent $InprocServer32.ValueContent $Category $_.PSComputerName
                }
            }

        $BootVer = Get-CSRegistryValue -Hive HKLM -SubKey 'SYSTEM\CurrentControlSet\Control\BootVerificationProgram' -ValueName 'ImagePath' @CommonArgs @Timeout

        if ($BootVer) {
            $BootVer | New-AutoRunsEntry -Hive $BootVer.Hive -SubKey "$($BootVer.SubKey)\ImagePath"
        }

        foreach ($SID in $HKUSIDs) {
            $Scrnsave = Get-CSRegistryValue -Hive HKU -SubKey "$SID\SOFTWARE\Policies\Microsoft\Windows\Control Panel\Desktop" -ValueName 'Scrnsave.exe' @CommonArgs @Timeout
            if ($Scrnsave) { $Scrnsave | New-AutoRunsEntry }

            $Scrnsave = Get-CSRegistryValue -Hive HKU -SubKey "$SID\Control Panel\Desktop" -ValueName 'Scrnsave.exe' @CommonArgs @Timeout
            if ($Scrnsave) { $Scrnsave | New-AutoRunsEntry }
        }
    }
    #>
}

function Get-SecurityPackage
{
    param
    (
        [Parameter()]
        [switch]
        $ReturnHashtables
    )
    <#
    .SYNOPSIS

    Enumerates Security Service Providers (SSP) t

    .DESCRIPTION   

    .NOTES

    Author: Jared Atkinson (@jaredcatkinson)
    License: BSD 3-Clause
    Required Dependencies: None
    Optional Dependencies: None

    .EXAMPLE

    PS > Get-SecurityPackage

    Name         : Negotiate
    Comment      : Microsoft Package Negotiator
    Capabilities : INTEGRITY, PRIVACY, CONNECTION, MULTI_REQUIRED, EXTENDED_ERROR, 
                   IMPERSONATION, ACCEPT_WIN32_NAME, NEGOTIABLE, GSS_COMPATIBLE, LOGON, 
                   RESTRICTED_TOKENS, APPCONTAINER_CHECKS
    Version      : 1
    RpcId        : 9
    MaxToken     : 65791

    Name         : NegoExtender
    Comment      : NegoExtender Security Package
    Capabilities : INTEGRITY, PRIVACY, CONNECTION, IMPERSONATION, NEGOTIABLE, GSS_COMPATIBLE, 
                   LOGON, MUTUAL_AUTH, NEGO_EXTENDER, APPCONTAINER_CHECKS
    Version      : 1
    RpcId        : 30
    MaxToken     : 12000

    Name         : Kerberos
    Comment      : Microsoft Kerberos V1.0
    Capabilities : INTEGRITY, PRIVACY, TOKEN_ONLY, DATAGRAM, CONNECTION, MULTI_REQUIRED, 
                   EXTENDED_ERROR, IMPERSONATION, ACCEPT_WIN32_NAME, NEGOTIABLE, 
                   GSS_COMPATIBLE, LOGON, MUTUAL_AUTH, DELEGATION, READONLY_WITH_CHECKSUM, 
                   RESTRICTED_TOKENS, APPCONTAINER_CHECKS
    Version      : 1
    RpcId        : 16
    MaxToken     : 65535

    Name         : NTLM
    Comment      : NTLM Security Package
    Capabilities : INTEGRITY, PRIVACY, TOKEN_ONLY, CONNECTION, MULTI_REQUIRED, IMPERSONATION, 
                   ACCEPT_WIN32_NAME, NEGOTIABLE, LOGON, RESTRICTED_TOKENS, APPCONTAINER_CHECKS
    Version      : 1
    RpcId        : 10
    MaxToken     : 2888

    Name         : TSSSP
    Comment      : TS Service Security Package
    Capabilities : CONNECTION, MULTI_REQUIRED, ACCEPT_WIN32_NAME, MUTUAL_AUTH, 
                   APPCONTAINER_CHECKS
    Version      : 1
    RpcId        : 22
    MaxToken     : 13000

    Name         : pku2u
    Comment      : PKU2U Security Package
    Capabilities : INTEGRITY, PRIVACY, CONNECTION, IMPERSONATION, GSS_COMPATIBLE, MUTUAL_AUTH, 
                   NEGOTIABLE2, APPCONTAINER_CHECKS
    Version      : 1
    RpcId        : 31
    MaxToken     : 12000

    Name         : CloudAP
    Comment      : Cloud AP Security Package
    Capabilities : LOGON, NEGOTIABLE2
    Version      : 1
    RpcId        : 36
    MaxToken     : 0

    Name         : WDigest
    Comment      : Digest Authentication for Windows
    Capabilities : TOKEN_ONLY, IMPERSONATION, ACCEPT_WIN32_NAME, APPCONTAINER_CHECKS
    Version      : 1
    RpcId        : 21
    MaxToken     : 4096

    Name         : Schannel
    Comment      : Schannel Security Package
    Capabilities : INTEGRITY, PRIVACY, CONNECTION, MULTI_REQUIRED, EXTENDED_ERROR, 
                   IMPERSONATION, ACCEPT_WIN32_NAME, STREAM, MUTUAL_AUTH, 
                   APPCONTAINER_PASSTHROUGH
    Version      : 1
    RpcId        : 14
    MaxToken     : 24576

    Name         : Microsoft Unified Security Protocol Provider
    Comment      : Schannel Security Package
    Capabilities : INTEGRITY, PRIVACY, CONNECTION, MULTI_REQUIRED, EXTENDED_ERROR, 
                   IMPERSONATION, ACCEPT_WIN32_NAME, STREAM, MUTUAL_AUTH, 
                   APPCONTAINER_PASSTHROUGH
    Version      : 1
    RpcId        : 14
    MaxToken     : 24576

    Name         : CREDSSP
    Comment      : Microsoft CredSSP Security Provider
    Capabilities : INTEGRITY, PRIVACY, CONNECTION, MULTI_REQUIRED, IMPERSONATION, 
                   ACCEPT_WIN32_NAME, STREAM, MUTUAL_AUTH, APPCONTAINER_CHECKS
    Version      : 1
    RpcId        : 65535
    MaxToken     : 90567
    #>

    $obj = EnumerateSecurityPackages

    if($ReturnHashtables)
    {
        foreach($o in $obj)
        {
            $props = @{
                Name = $o.Name
                Comment = $o.Comment
                Capabilities = $o.Capabilities
                Version = $o.Version
                RpcId = $o.RpcId
                MaxToken = $o.MaxToken
            }

            Write-Output $props
        }
    }
    else
    {
        Write-Output $obj
    }
}

function Get-SimpleNamedPipe
{ 
<#
    .SYNOPSIS

        Gets a list of open named pipes.

        Author: Greg Zakharov
        License: 
        Required Dependencies: None
        Optional Dependencies: None

    .DESCRIPTION

        When defining custom enums, structs, and unmanaged functions, it is
        necessary to associate to an assembly module. This helper function
        creates an in-memory module that can be passed to the 'enum',
        'struct', and Add-Win32Type functions.
#>
    [CmdletBinding()]
    Param (
        [switch]
        $ReturnHashtables
    )

    Begin 
    {
        $Mscorlib = [AppDomain]::CurrentDomain.GetAssemblies() | ? { 
            $_.ManifestModule.ScopeName.Equals('CommonLanguageRuntimeLibrary') 
        } 
     
        $SafeFindHandle = $Mscorlib.GetType('Microsoft.Win32.SafeHandles.SafeFindHandle') 
        $Win32Native = $Mscorlib.GetType('Microsoft.Win32.Win32Native') 
     
        $WIN32_FIND_DATA = $Win32Native.GetNestedType( 
            'WIN32_FIND_DATA', [Reflection.BindingFlags]32 
        ) 
        $FindFirstFile = $Win32Native.GetMethod( 
            'FindFirstFile', [Reflection.BindingFlags]40, 
            $null, @([String], $WIN32_FIND_DATA), $null 
        ) 
        $FindNextFile = $Win32Native.GetMethod('FindNextFile', [Reflection.BindingFlags]40, $null, @($SafeFindHandle, $WIN32_FIND_DATA), $null) 
     
        $Obj = $WIN32_FIND_DATA.GetConstructors()[0].Invoke($null)
        function Read-Field([String]$Field) { 
            return $WIN32_FIND_DATA.GetField($Field, [Reflection.BindingFlags]36).GetValue($Obj)
        } 
    } 

    Process 
    { 
        $Handle = $FindFirstFile.Invoke($null, @('\\.\pipe\*', $obj))

        
        $Output = @{
            Name = [string](Read-Field cFileName)
            Instances = [UInt32](Read-Field nFileSizeLow)
        }

        do {
            $Output = @{
                Name = [string](Read-Field cFileName)
                Instances = [UInt32](Read-Field nFileSizeLow)
            }

            if($ReturnHashtables) {
                $Output
            } else {
                New-Object PSObject -Property $Output
            }
        } while($FindNextFile.Invoke($null, @($Handle, $obj)))
     
        $Handle.Close() 
    } 

    End 
    {
    
    } 
}

function Get-WmiEventSubscription
{
    foreach($o in (Get-WmiObject -Namespace root\subscription -Class __EventConsumer))
    {
        $Sid = New-Object System.Security.Principal.SecurityIdentifier(@($o.CreatorSID,$null))
        $UserName = $Sid.Translate([System.Security.Principal.NTAccount])
        
        switch($o.__CLASS)
        {
            ActiveScriptEventConsumer
            {
                $props = @{
                    CreatorSid = $Sid.Value
                    CreatorUserName = $UserName
                    KillTimeout = $o.KillTimeout
                    MachineName = $o.MachineName
                    MaximumQueueSize = $o.MaximumQueueSize
                    Name = $o.Name
                    ScriptFilename = $o.ScriptFilename
                    ScriptingEngine = $o.ScriptingEngine
                    ScriptText = $o.ScriptText
                    Class = $o.ClassPath.ClassName
                    ClassPath = $o.ClassPath.Path
                }
            }
            CommandLineEventConsumer
            {
                $props = @{
                    CreatorSid = $Sid.Value
                    CreatorUserName = $UserName
                    MachineName = $o.MachineName
                    MaximumQueueSize = $o.MaximumQueueSize
                    CommandLineTemplate = $o.CommandLineTemplate
                    CreateNewConsole = $o.CreateNewConsole
                    CreateNewProcessGroup = $o.CreateNewProcessGroup
                    CreateSeparateWowVdm = $o.CreateSeparateWowVdm
                    CreateSharedWowVdm = $o.CreateSharedWowVdm
                    DesktopName = $o.DesktopName
                    ExecutablePath = $o.ExecutablePath
                    FillAttributes = $o.FillAttributes
                    ForceOffFeedback = $o.ForceOffFeedback
                    ForceOnFeedback = $o.ForceOnFeedback
                    KillTimeout = $o.KillTimeout
                    Name = $o.Name
                    Priority = $o.Priority
                    RunInteractively = $o.RunInteractively
                    ShowWindowCommand = $o.ShowWindowCommand
                    UseDefaultErrorMode = $o.UseDefaultErrorMode
                    WindowTitle = $o.WindowTitle
                    WorkingDirectory = $o.WorkingDirectory
                    XCoordinate = $o.XCoordinate
                    XNumCharacters = $o.XNumCharacters
                    XSize = $o.XSize
                    YCoordinate = $o.YCoordinate
                    YNumCharacters = $o.YNumCharacters
                    YSize = $o.YSize
                    FillAttribute = $o.FillAttribute
                    Class = $o.ClassPath.ClassName
                    ClassPath = $o.ClassPath.Path
                }
            }
            LogFileEventConsumer
            {
                $props = @{
                    CreatorSid = $Sid.Value
                    CreatorUserName = $UserName
                    MachineName = $o.MachineName
                    MaximumQueueSize = $o.MaximumQueueSize
                    Filename = $o.Filename
                    IsUnicode = $o.IsUnicode
                    MaximumFileSize = $o.MaximumFileSize
                    Name = $o.Name
                    Text = $o.Text
                    Class = $o.ClassPath.ClassName
                    ClassPath = $o.ClassPath.Path
                }
            }
            NtEventLogEventConsumer
            {
                $props = @{
                    Category = $o.Category
                    CreatorSid = $Sid.Value
                    CreatorUserName = $UserName
                    EventId = $o.EventID
                    EventType = $o.EventType
                    InsertionStringTemplates = $o.InsertionStringTemplates
                    MachineName = $o.MachineName
                    MaximumQueueSize = $o.MaximumQueueSize
                    Name = $o.Name
                    NameOfRawDataProperty = $o.NameOfRawDataProperty
                    NameOfUserSidProperty = $o.NameOfUserSIDProperty
                    NumberOfInsertionStrings = $o.NumberOfInsertionStrings
                    SourceName = $o.SourceName
                    UncServerName = $o.UNCServerName
                    Class = $o.ClassPath.ClassName
                    ClassPath = $o.ClassPath.Path
                }
            }
            SMTPEventConsumer
            {
                $props = @{
                    CreatorSid = $Sid.Value
                    CreatorUserName = $UserName
                    MachineName = $o.MachineName
                    MaximumQueueSize = $o.MaximumQueueSize
                    BccLine = $o.BccLine
                    CcLine = $o.CcLine
                    FromLine = $o.FromLine
                    HeaderFields = $o.HeaderFields
                    Message = $o.Message
                    Name = $o.Name
                    ReplyToLine = $o.ReplyToLine
                    SMTPServer = $o.SMTPServer
                    Subject = $o.Subject
                    ToLine = $o.ToLine
                    Class = $o.ClassPath.ClassName
                    ClassPath = $o.ClassPath.Path
                }
            }
            default
            {
                $props = @{
                    CreatorSid = $Sid.Value
                    CreatorUserName = $UserName
                    Name = $o.Name
                    Class = $o.ClassPath.ClassName
                    ClassPath = $o.ClassPath.Path
                }
            }
        }
        Write-Output $props
    }
}
#endregion Collection Functions

#region Helper Functions
function Get-System
{
    <#
    .SYNOPSIS

    .DESCRIPTION

    .NOTES

    Author: Jared Atkinson (@jaredcatkinson)
    License: BSD 3-Clause
    Required Dependencies: None
    Optional Dependencies: None
        
    .LINK

    .EXAMPLE
    #>

    # Get a Process object for the winlogon process
    # The System.Diagnostics.Process class has a handle property that we can use
    # We know winlogon will be available and is running as NT AUTHORITY\SYSTEM
    $winlogons = Get-Process -Name winlogon

    try
    {
        $proc = $winlogons[0]
    }
    catch
    {
        $proc = $winlogons
    }

    # Open winlogon's Token with TOKEN_DUPLICATE Acess
    # This allows us to make a copy of the token with DuplicateToken
    $hToken = OpenProcessToken -ProcessHandle $proc.Handle -DesiredAccess TOKEN_DUPLICATE
    
    # Make a copy of the NT AUTHORITY\SYSTEM Token
    $hDupToken = DuplicateToken -TokenHandle $hToken
    
    # Apply our Duplicated Token to our Thread
    ImpersonateLoggedOnUser -TokenHandle $hDupToken
    
    # Clean up the handles we created
    CloseHandle -Handle $hToken
    CloseHandle -Handle $hDupToken

    if(-not [System.Security.Principal.WindowsIdentity]::GetCurrent().Name -eq 'NT AUTHORITY\SYSTEM')
    {
        throw "Unable to Impersonate System Token"
    }
}

function Get-RegistryValue
{
    param
    (
        [Parameter(Mandatory = $true)]
        [string[]]
        $Key,

        [Parameter()]
        [string[]]
        $Value
    )

    foreach($k in $key)
    {
        try
        {
            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\)' }))
            {
                if($PSBoundParameters.ContainsKey('Value'))
                {
                    if($Value -contains $val.Name)
                    {
                        $props = @{
                            Path = $k
                            Name = $val.Name
                            Value = $val.Value
                        }

                        New-Object -TypeName psobject -Property $props
                    }
                }
                else
                {
                    $props = @{
                        Path = $k
                        Name = $val.Name
                        Value = $val.Value
                    }

                    New-Object -TypeName psobject -Property $props
                }
            }
        }
        catch
        {

        }
    }
}

function New-AutoRunEntry
{
    param
    (
        [Parameter(Position = 0, ValueFromPipelineByPropertyName = $true)]
        [string]
        $Path,
    
        [Parameter(Position = 1, ValueFromPipelineByPropertyName = $true)]
        [string]
        $Name,

        [Parameter(Position = 2, ValueFromPipelineByPropertyName = $true)]
        [Alias('Value')]
        [string]
        $ImagePath,

        [Parameter(Position = 3, ValueFromPipelineByPropertyName = $true)]
        [string]
        $Category
    )

    process
    {
        if($ImagePath -ne $null)
        {
            @{
                Path = $Path
                Name = $Name
                ImagePath = $ImagePath
                Type = $Category
            }
        }
    }
}
#endregion Helper Functions

#region PSReflect
function New-InMemoryModule
{
<#
.SYNOPSIS

Creates an in-memory assembly and module

Author: Matthew Graeber (@mattifestation)
License: BSD 3-Clause
Required Dependencies: None
Optional Dependencies: None
 
.DESCRIPTION

When defining custom enums, structs, and unmanaged functions, it is
necessary to associate to an assembly module. This helper function
creates an in-memory module that can be passed to the 'enum',
'struct', and Add-Win32Type functions.

.PARAMETER ModuleName

Specifies the desired name for the in-memory assembly and module. If
ModuleName is not provided, it will default to a GUID.

.EXAMPLE

$Module = New-InMemoryModule -ModuleName Win32
#>

    Param
    (
        [Parameter(Position = 0)]
        [ValidateNotNullOrEmpty()]
        [String]
        $ModuleName = [Guid]::NewGuid().ToString()
    )

    $AppDomain = [Reflection.Assembly].Assembly.GetType('System.AppDomain').GetProperty('CurrentDomain').GetValue($null, @())
    $LoadedAssemblies = $AppDomain.GetAssemblies()

    foreach ($Assembly in $LoadedAssemblies) {
        if ($Assembly.FullName -and ($Assembly.FullName.Split(',')[0] -eq $ModuleName)) {
            return $Assembly
        }
    }

    $DynAssembly = New-Object Reflection.AssemblyName($ModuleName)
    $Domain = $AppDomain
    $AssemblyBuilder = $Domain.DefineDynamicAssembly($DynAssembly, 'Run')
    $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule($ModuleName, $False)

    return $ModuleBuilder
}

# A helper function used to reduce typing while defining function
# prototypes for Add-Win32Type.
function func
{
    Param
    (
        [Parameter(Position = 0, Mandatory = $True)]
        [String]
        $DllName,

        [Parameter(Position = 1, Mandatory = $True)]
        [string]
        $FunctionName,

        [Parameter(Position = 2, Mandatory = $True)]
        [Type]
        $ReturnType,

        [Parameter(Position = 3)]
        [Type[]]
        $ParameterTypes,

        [Parameter(Position = 4)]
        [Runtime.InteropServices.CallingConvention]
        $NativeCallingConvention,

        [Parameter(Position = 5)]
        [Runtime.InteropServices.CharSet]
        $Charset,

        [String]
        $EntryPoint,

        [Switch]
        $SetLastError
    )

    $Properties = @{
        DllName = $DllName
        FunctionName = $FunctionName
        ReturnType = $ReturnType
    }

    if ($ParameterTypes) { $Properties['ParameterTypes'] = $ParameterTypes }
    if ($NativeCallingConvention) { $Properties['NativeCallingConvention'] = $NativeCallingConvention }
    if ($Charset) { $Properties['Charset'] = $Charset }
    if ($SetLastError) { $Properties['SetLastError'] = $SetLastError }
    if ($EntryPoint) { $Properties['EntryPoint'] = $EntryPoint }

    New-Object PSObject -Property $Properties
}

function Add-Win32Type
{
<#
.SYNOPSIS

Creates a .NET type for an unmanaged Win32 function.

Author: Matthew Graeber (@mattifestation)
License: BSD 3-Clause
Required Dependencies: None
Optional Dependencies: func
 
.DESCRIPTION

Add-Win32Type enables you to easily interact with unmanaged (i.e.
Win32 unmanaged) functions in PowerShell. After providing
Add-Win32Type with a function signature, a .NET type is created
using reflection (i.e. csc.exe is never called like with Add-Type).

The 'func' helper function can be used to reduce typing when defining
multiple function definitions.

.PARAMETER DllName

The name of the DLL.

.PARAMETER FunctionName

The name of the target function.

.PARAMETER EntryPoint

The DLL export function name. This argument should be specified if the
specified function name is different than the name of the exported
function.

.PARAMETER ReturnType

The return type of the function.

.PARAMETER ParameterTypes

The function parameters.

.PARAMETER NativeCallingConvention

Specifies the native calling convention of the function. Defaults to
stdcall.

.PARAMETER Charset

If you need to explicitly call an 'A' or 'W' Win32 function, you can
specify the character set.

.PARAMETER SetLastError

Indicates whether the callee calls the SetLastError Win32 API
function before returning from the attributed method.

.PARAMETER Module

The in-memory module that will host the functions. Use
New-InMemoryModule to define an in-memory module.

.PARAMETER Namespace

An optional namespace to prepend to the type. Add-Win32Type defaults
to a namespace consisting only of the name of the DLL.

.EXAMPLE

$Mod = New-InMemoryModule -ModuleName Win32

$FunctionDefinitions = @(
    (func kernel32 GetProcAddress ([IntPtr]) @([IntPtr], [String]) -Charset Ansi -SetLastError),
    (func kernel32 GetModuleHandle ([Intptr]) @([String]) -SetLastError),
    (func ntdll RtlGetCurrentPeb ([IntPtr]) @())
)

$Types = $FunctionDefinitions | Add-Win32Type -Module $Mod -Namespace 'Win32'
$Kernel32 = $Types['kernel32']
$Ntdll = $Types['ntdll']
$Ntdll::RtlGetCurrentPeb()
$ntdllbase = $Kernel32::GetModuleHandle('ntdll')
$Kernel32::GetProcAddress($ntdllbase, 'RtlGetCurrentPeb')

.NOTES

Inspired by Lee Holmes' Invoke-WindowsApi http://poshcode.org/2189

When defining multiple function prototypes, it is ideal to provide
Add-Win32Type with an array of function signatures. That way, they
are all incorporated into the same in-memory module.
#>

    [OutputType([Hashtable])]
    Param(
        [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)]
        [String]
        $DllName,

        [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)]
        [String]
        $FunctionName,

        [Parameter(ValueFromPipelineByPropertyName = $True)]
        [String]
        $EntryPoint,

        [Parameter(Mandatory = $True, ValueFromPipelineByPropertyName = $True)]
        [Type]
        $ReturnType,

        [Parameter(ValueFromPipelineByPropertyName = $True)]
        [Type[]]
        $ParameterTypes,

        [Parameter(ValueFromPipelineByPropertyName = $True)]
        [Runtime.InteropServices.CallingConvention]
        $NativeCallingConvention = [Runtime.InteropServices.CallingConvention]::StdCall,

        [Parameter(ValueFromPipelineByPropertyName = $True)]
        [Runtime.InteropServices.CharSet]
        $Charset = [Runtime.InteropServices.CharSet]::Auto,

        [Parameter(ValueFromPipelineByPropertyName = $True)]
        [Switch]
        $SetLastError,

        [Parameter(Mandatory = $True)]
        [ValidateScript({($_ -is [Reflection.Emit.ModuleBuilder]) -or ($_ -is [Reflection.Assembly])})]
        $Module,

        [ValidateNotNull()]
        [String]
        $Namespace = ''
    )

    BEGIN
    {
        $TypeHash = @{}
    }

    PROCESS
    {
        if ($Module -is [Reflection.Assembly])
        {
            if ($Namespace)
            {
                $TypeHash[$DllName] = $Module.GetType("$Namespace.$DllName")
            }
            else
            {
                $TypeHash[$DllName] = $Module.GetType($DllName)
            }
        }
        else
        {
            # Define one type for each DLL
            if (!$TypeHash.ContainsKey($DllName))
            {
                if ($Namespace)
                {
                    $TypeHash[$DllName] = $Module.DefineType("$Namespace.$DllName", 'Public,BeforeFieldInit')
                }
                else
                {
                    $TypeHash[$DllName] = $Module.DefineType($DllName, 'Public,BeforeFieldInit')
                }
            }

            $Method = $TypeHash[$DllName].DefineMethod(
                $FunctionName,
                'Public,Static,PinvokeImpl',
                $ReturnType,
                $ParameterTypes)

            # Make each ByRef parameter an Out parameter
            $i = 1
            foreach($Parameter in $ParameterTypes)
            {
                if ($Parameter.IsByRef)
                {
                    [void] $Method.DefineParameter($i, 'Out', $null)
                }

                $i++
            }

            $DllImport = [Runtime.InteropServices.DllImportAttribute]
            $SetLastErrorField = $DllImport.GetField('SetLastError')
            $CallingConventionField = $DllImport.GetField('CallingConvention')
            $CharsetField = $DllImport.GetField('CharSet')
            $EntryPointField = $DllImport.GetField('EntryPoint')
            if ($SetLastError) { $SLEValue = $True } else { $SLEValue = $False }

            if ($PSBoundParameters['EntryPoint']) { $ExportedFuncName = $EntryPoint } else { $ExportedFuncName = $FunctionName }

            # Equivalent to C# version of [DllImport(DllName)]
            $Constructor = [Runtime.InteropServices.DllImportAttribute].GetConstructor([String])
            $DllImportAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($Constructor,
                $DllName, [Reflection.PropertyInfo[]] @(), [Object[]] @(),
                [Reflection.FieldInfo[]] @($SetLastErrorField,
                                            $CallingConventionField,
                                            $CharsetField,
                                            $EntryPointField),
                [Object[]] @($SLEValue,
                                ([Runtime.InteropServices.CallingConvention] $NativeCallingConvention),
                                ([Runtime.InteropServices.CharSet] $Charset),
                                $ExportedFuncName))

            $Method.SetCustomAttribute($DllImportAttribute)
        }
    }

    END
    {
        if ($Module -is [Reflection.Assembly])
        {
            return $TypeHash
        }

        $ReturnTypes = @{}

        foreach ($Key in $TypeHash.Keys)
        {
            $Type = $TypeHash[$Key].CreateType()
            
            $ReturnTypes[$Key] = $Type
        }

        return $ReturnTypes
    }
}

function psenum
{
<#
.SYNOPSIS

Creates an in-memory enumeration for use in your PowerShell session.

Author: Matthew Graeber (@mattifestation)
License: BSD 3-Clause
Required Dependencies: None
Optional Dependencies: None
 
.DESCRIPTION

The 'psenum' function facilitates the creation of enums entirely in
memory using as close to a "C style" as PowerShell will allow.

.PARAMETER Module

The in-memory module that will host the enum. Use
New-InMemoryModule to define an in-memory module.

.PARAMETER FullName

The fully-qualified name of the enum.

.PARAMETER Type

The type of each enum element.

.PARAMETER EnumElements

A hashtable of enum elements.

.PARAMETER Bitfield

Specifies that the enum should be treated as a bitfield.

.EXAMPLE

$Mod = New-InMemoryModule -ModuleName Win32

$ImageSubsystem = psenum $Mod PE.IMAGE_SUBSYSTEM UInt16 @{
    UNKNOWN =                  0
    NATIVE =                   1 # Image doesn't require a subsystem.
    WINDOWS_GUI =              2 # Image runs in the Windows GUI subsystem.
    WINDOWS_CUI =              3 # Image runs in the Windows character subsystem.
    OS2_CUI =                  5 # Image runs in the OS/2 character subsystem.
    POSIX_CUI =                7 # Image runs in the Posix character subsystem.
    NATIVE_WINDOWS =           8 # Image is a native Win9x driver.
    WINDOWS_CE_GUI =           9 # Image runs in the Windows CE subsystem.
    EFI_APPLICATION =          10
    EFI_BOOT_SERVICE_DRIVER =  11
    EFI_RUNTIME_DRIVER =       12
    EFI_ROM =                  13
    XBOX =                     14
    WINDOWS_BOOT_APPLICATION = 16
}

.NOTES

PowerShell purists may disagree with the naming of this function but
again, this was developed in such a way so as to emulate a "C style"
definition as closely as possible. Sorry, I'm not going to name it
New-Enum. :P
#>

    [OutputType([Type])]
    Param
    (
        [Parameter(Position = 0, Mandatory = $True)]
        [ValidateScript({($_ -is [Reflection.Emit.ModuleBuilder]) -or ($_ -is [Reflection.Assembly])})]
        $Module,

        [Parameter(Position = 1, Mandatory = $True)]
        [ValidateNotNullOrEmpty()]
        [String]
        $FullName,

        [Parameter(Position = 2, Mandatory = $True)]
        [Type]
        $Type,

        [Parameter(Position = 3, Mandatory = $True)]
        [ValidateNotNullOrEmpty()]
        [Hashtable]
        $EnumElements,

        [Switch]
        $Bitfield
    )

    if ($Module -is [Reflection.Assembly])
    {
        return ($Module.GetType($FullName))
    }

    $EnumType = $Type -as [Type]

    $EnumBuilder = $Module.DefineEnum($FullName, 'Public', $EnumType)

    if ($Bitfield)
    {
        $FlagsConstructor = [FlagsAttribute].GetConstructor(@())
        $FlagsCustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($FlagsConstructor, @())
        $EnumBuilder.SetCustomAttribute($FlagsCustomAttribute)
    }

    foreach ($Key in $EnumElements.Keys)
    {
        # Apply the specified enum type to each element
        $null = $EnumBuilder.DefineLiteral($Key, $EnumElements[$Key] -as $EnumType)
    }

    $EnumBuilder.CreateType()
}

# A helper function used to reduce typing while defining struct
# fields.
function field
{
    Param
    (
        [Parameter(Position = 0, Mandatory = $True)]
        [UInt16]
        $Position,
        
        [Parameter(Position = 1, Mandatory = $True)]
        [Type]
        $Type,
        
        [Parameter(Position = 2)]
        [UInt16]
        $Offset,
        
        [Object[]]
        $MarshalAs
    )

    @{
        Position = $Position
        Type = $Type -as [Type]
        Offset = $Offset
        MarshalAs = $MarshalAs
    }
}

function struct
{
<#
.SYNOPSIS

Creates an in-memory struct for use in your PowerShell session.

Author: Matthew Graeber (@mattifestation)
License: BSD 3-Clause
Required Dependencies: None
Optional Dependencies: field
 
.DESCRIPTION

The 'struct' function facilitates the creation of structs entirely in
memory using as close to a "C style" as PowerShell will allow. Struct
fields are specified using a hashtable where each field of the struct
is comprosed of the order in which it should be defined, its .NET
type, and optionally, its offset and special marshaling attributes.

One of the features of 'struct' is that after your struct is defined,
it will come with a built-in GetSize method as well as an explicit
converter so that you can easily cast an IntPtr to the struct without
relying upon calling SizeOf and/or PtrToStructure in the Marshal
class.

.PARAMETER Module

The in-memory module that will host the struct. Use
New-InMemoryModule to define an in-memory module.

.PARAMETER FullName

The fully-qualified name of the struct.

.PARAMETER StructFields

A hashtable of fields. Use the 'field' helper function to ease
defining each field.

.PARAMETER PackingSize

Specifies the memory alignment of fields.

.PARAMETER ExplicitLayout

Indicates that an explicit offset for each field will be specified.

.EXAMPLE

$Mod = New-InMemoryModule -ModuleName Win32

$ImageDosSignature = psenum $Mod PE.IMAGE_DOS_SIGNATURE UInt16 @{
    DOS_SIGNATURE =    0x5A4D
    OS2_SIGNATURE =    0x454E
    OS2_SIGNATURE_LE = 0x454C
    VXD_SIGNATURE =    0x454C
}

$ImageDosHeader = struct $Mod PE.IMAGE_DOS_HEADER @{
    e_magic =    field 0 $ImageDosSignature
    e_cblp =     field 1 UInt16
    e_cp =       field 2 UInt16
    e_crlc =     field 3 UInt16
    e_cparhdr =  field 4 UInt16
    e_minalloc = field 5 UInt16
    e_maxalloc = field 6 UInt16
    e_ss =       field 7 UInt16
    e_sp =       field 8 UInt16
    e_csum =     field 9 UInt16
    e_ip =       field 10 UInt16
    e_cs =       field 11 UInt16
    e_lfarlc =   field 12 UInt16
    e_ovno =     field 13 UInt16
    e_res =      field 14 UInt16[] -MarshalAs @('ByValArray', 4)
    e_oemid =    field 15 UInt16
    e_oeminfo =  field 16 UInt16
    e_res2 =     field 17 UInt16[] -MarshalAs @('ByValArray', 10)
    e_lfanew =   field 18 Int32
}

# Example of using an explicit layout in order to create a union.
$TestUnion = struct $Mod TestUnion @{
    field1 = field 0 UInt32 0
    field2 = field 1 IntPtr 0
} -ExplicitLayout

.NOTES

PowerShell purists may disagree with the naming of this function but
again, this was developed in such a way so as to emulate a "C style"
definition as closely as possible. Sorry, I'm not going to name it
New-Struct. :P
#>

    [OutputType([Type])]
    Param
    (
        [Parameter(Position = 1, Mandatory = $True)]
        [ValidateScript({($_ -is [Reflection.Emit.ModuleBuilder]) -or ($_ -is [Reflection.Assembly])})]
        $Module,

        [Parameter(Position = 2, Mandatory = $True)]
        [ValidateNotNullOrEmpty()]
        [String]
        $FullName,

        [Parameter(Position = 3, Mandatory = $True)]
        [ValidateNotNullOrEmpty()]
        [Hashtable]
        $StructFields,

        [Reflection.Emit.PackingSize]
        $PackingSize = [Reflection.Emit.PackingSize]::Unspecified,

        [Switch]
        $ExplicitLayout
    )

    if ($Module -is [Reflection.Assembly])
    {
        return ($Module.GetType($FullName))
    }

    [Reflection.TypeAttributes] $StructAttributes = 'AnsiClass,
        Class,
        Public,
        Sealed,
        BeforeFieldInit'

    if ($ExplicitLayout)
    {
        $StructAttributes = $StructAttributes -bor [Reflection.TypeAttributes]::ExplicitLayout
    }
    else
    {
        $StructAttributes = $StructAttributes -bor [Reflection.TypeAttributes]::SequentialLayout
    }

    $StructBuilder = $Module.DefineType($FullName, $StructAttributes, [ValueType], $PackingSize)
    $ConstructorInfo = [Runtime.InteropServices.MarshalAsAttribute].GetConstructors()[0]
    $SizeConst = @([Runtime.InteropServices.MarshalAsAttribute].GetField('SizeConst'))

    $Fields = New-Object Hashtable[]($StructFields.Count)

    # Sort each field according to the orders specified
    # Unfortunately, PSv2 doesn't have the luxury of the
    # hashtable [Ordered] accelerator.
    foreach ($Field in $StructFields.Keys)
    {
        $Index = $StructFields[$Field]['Position']
        $Fields[$Index] = @{FieldName = $Field; Properties = $StructFields[$Field]}
    }

    foreach ($Field in $Fields)
    {
        $FieldName = $Field['FieldName']
        $FieldProp = $Field['Properties']

        $Offset = $FieldProp['Offset']
        $Type = $FieldProp['Type']
        $MarshalAs = $FieldProp['MarshalAs']

        $NewField = $StructBuilder.DefineField($FieldName, $Type, 'Public')

        if ($MarshalAs)
        {
            $UnmanagedType = $MarshalAs[0] -as ([Runtime.InteropServices.UnmanagedType])
            if ($MarshalAs[1])
            {
                $Size = $MarshalAs[1]
                $AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($ConstructorInfo,
                    $UnmanagedType, $SizeConst, @($Size))
            }
            else
            {
                $AttribBuilder = New-Object Reflection.Emit.CustomAttributeBuilder($ConstructorInfo, [Object[]] @($UnmanagedType))
            }
            
            $NewField.SetCustomAttribute($AttribBuilder)
        }

        if ($ExplicitLayout) { $NewField.SetOffset($Offset) }
    }

    # Make the struct aware of its own size.
    # No more having to call [Runtime.InteropServices.Marshal]::SizeOf!
    $SizeMethod = $StructBuilder.DefineMethod('GetSize',
        'Public, Static',
        [Int],
        [Type[]] @())
    $ILGenerator = $SizeMethod.GetILGenerator()
    # Thanks for the help, Jason Shirk!
    $ILGenerator.Emit([Reflection.Emit.OpCodes]::Ldtoken, $StructBuilder)
    $ILGenerator.Emit([Reflection.Emit.OpCodes]::Call,
        [Type].GetMethod('GetTypeFromHandle'))
    $ILGenerator.Emit([Reflection.Emit.OpCodes]::Call,
        [Runtime.InteropServices.Marshal].GetMethod('SizeOf', [Type[]] @([Type])))
    $ILGenerator.Emit([Reflection.Emit.OpCodes]::Ret)

    # Allow for explicit casting from an IntPtr
    # No more having to call [Runtime.InteropServices.Marshal]::PtrToStructure!
    $ImplicitConverter = $StructBuilder.DefineMethod('op_Implicit',
        'PrivateScope, Public, Static, HideBySig, SpecialName',
        $StructBuilder,
        [Type[]] @([IntPtr]))
    $ILGenerator2 = $ImplicitConverter.GetILGenerator()
    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Nop)
    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ldarg_0)
    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ldtoken, $StructBuilder)
    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Call,
        [Type].GetMethod('GetTypeFromHandle'))
    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Call,
        [Runtime.InteropServices.Marshal].GetMethod('PtrToStructure', [Type[]] @([IntPtr], [Type])))
    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Unbox_Any, $StructBuilder)
    $ILGenerator2.Emit([Reflection.Emit.OpCodes]::Ret)

    $StructBuilder.CreateType()
}
#endregion PSReflect

$Module = New-InMemoryModule -ModuleName ACE

#region Enums
$KERB_PROTOCOL_MESSAGE_TYPE = psenum $Module KERB_PROTOCOL_MESSAGE_TYPE UInt32 @{ 
    KerbDebugRequestMessage                  = 0
    KerbQueryTicketCacheMessage              = 1
    KerbChangeMachinePasswordMessage         = 2
    KerbVerifyPacMessage                     = 3
    KerbRetrieveTicketMessage                = 4
    KerbUpdateAddressesMessage               = 5
    KerbPurgeTicketCacheMessage              = 6
    KerbChangePasswordMessage                = 7
    KerbRetrieveEncodedTicketMessage         = 8
    KerbDecryptDataMessage                   = 9
    KerbAddBindingCacheEntryMessage          = 10
    KerbSetPasswordMessage                   = 11
    KerbSetPasswordExMessage                 = 12
    KerbVerifyCredentialsMessage             = 13
    KerbQueryTicketCacheExMessage            = 14
    KerbPurgeTicketCacheExMessage            = 15
    KerbRefreshSmartcardCredentialsMessage   = 16
    KerbAddExtraCredentialsMessage           = 17
    KerbQuerySupplementalCredentialsMessage  = 18
    KerbTransferCredentialsMessage           = 19
    KerbQueryTicketCacheEx2Message           = 20
    KerbSubmitTicketMessage                  = 21
    KerbAddExtraCredentialsExMessage         = 22
    KerbQueryKdcProxyCacheMessage            = 23
    KerbPurgeKdcProxyCacheMessage            = 24
    KerbQueryTicketCacheEx3Message           = 25
    KerbCleanupMachinePkinitCredsMessage     = 26
    KerbAddBindingCacheEntryExMessage        = 27
    KerbQueryBindingCacheMessage             = 28
    KerbPurgeBindingCacheMessage             = 29
    KerbQueryDomainExtendedPoliciesMessage   = 30
    KerbQueryS4U2ProxyCacheMessage           = 31
}

$KERB_CACHE_OPTIONS = psenum $Module KERB_CACHE_OPTIONS UInt64 @{
    KERB_RETRIEVE_TICKET_DONT_USE_CACHE = 0x1
    KERB_RETRIEVE_TICKET_USE_CACHE_ONLY = 0x2
    KERB_RETRIEVE_TICKET_USE_CREDHANDLE = 0x4
    KERB_RETRIEVE_TICKET_AS_KERB_CRED   = 0x8
    KERB_RETRIEVE_TICKET_WITH_SEC_CRED  = 0x10 
    KERB_RETRIEVE_TICKET_CACHE_TICKET   = 0x20
    KERB_RETRIEVE_TICKET_MAX_LIFETIME   = 0x40
} -Bitfield

$KERB_ENCRYPTION_TYPE = psenum $Module KERB_ENCRYPTION_TYPE UInt32 @{
        reserved0                         = 0
        des_cbc_crc                       = 1
        des_cbc_md4                       = 2
        des_cbc_md5                       = 3
        reserved1                         = 4
        des3_cbc_md5                      = 5
        reserved2                         = 6
        des3_cbc_sha1                     = 7
        dsaWithSHA1_CmsOID                = 9
        md5WithRSAEncryption_CmsOID       = 10
        sha1WithRSAEncryption_CmsOID      = 11
        rc2CBC_EnvOID                     = 12
        rsaEncryption_EnvOID              = 13
        rsaES_OAEP_ENV_OID                = 14
        des_ede3_cbc_Env_OID              = 15
        des3_cbc_sha1_kd                  = 16
        aes128_cts_hmac_sha1_96           = 17
        aes256_cts_hmac_sha1_96           = 18
        aes128_cts_hmac_sha256_128        = 19
        aes256_cts_hmac_sha384_192        = 20
        rc4_hmac                          = 23
        rc4_hmac_exp                      = 24
        camellia128_cts_cmac              = 25
        camellia256_cts_cmac              = 26
        subkey_keymaterial                = 65
}

$KERB_TICKET_FLAGS = psenum $Module KERB_TICKET_FLAGS UInt32 @{
    reserved          = 2147483648
    forwardable       = 0x40000000
    forwarded         = 0x20000000
    proxiable         = 0x10000000
    proxy             = 0x08000000
    may_postdate      = 0x04000000
    postdated         = 0x02000000
    invalid           = 0x01000000
    renewable         = 0x00800000
    initial           = 0x00400000
    pre_authent       = 0x00200000
    hw_authent        = 0x00100000
    ok_as_delegate    = 0x00040000
    name_canonicalize = 0x00010000
    cname_in_pa_data  = 0x00040000
    enc_pa_rep        = 0x00010000
    reserved1         = 0x00000001
} -Bitfield

$LuidAttributes = psenum $Module LuidAttributes UInt32 @{
    DISABLED                        = 0x00000000
    SE_PRIVILEGE_ENABLED_BY_DEFAULT = 0x00000001
    SE_PRIVILEGE_ENABLED            = 0x00000002
    SE_PRIVILEGE_REMOVED            = 0x00000004
    SE_PRIVILEGE_USED_FOR_ACCESS    = 2147483648
} -Bitfield

$MEMORY_PROTECTION = psenum $Module MEMORY_PROTECTION UInt32 @{
    PAGE_NOACCESS          = 0x00000001
    PAGE_READONLY          = 0x00000002
    PAGE_READWRITE         = 0x00000004
    PAGE_WRITECOPY         = 0x00000008
    PAGE_EXECUTE           = 0x00000010
    PAGE_EXECUTE_READ      = 0x00000020
    PAGE_EXECUTE_READWRITE = 0x00000040
    PAGE_EXECUTE_WRITECOPY = 0x00000080
    PAGE_GUARD             = 0x00000100
    PAGE_NOCACHE           = 0x00000200
    PAGE_WRITECOMBINE      = 0x00000400
    PAGE_TARGETS_NO_UPDATE = 0x40000000
} -Bitfield

$MEMORY_STATE = psenum $Module MEMORY_STATE UInt32 @{
    MEM_COMMIT  = 0x1000
    MEM_RESERVE = 0x2000
    MEM_FREE    = 0x10000
} -Bitfield

$MEMORY_TYPE = psenum $Module MEMORY_TYPE UInt32 @{
    MEM_PRIVATE = 0x20000
    MEM_MAPPED  = 0x40000
    MEM_IMAGE   = 0x1000000
} -Bitfield

$MIB_IPNET_TYPE = psenum $Module MIB_IPNET_TYPE UInt32 @{
    OTHER   = 1
    INVALID = 2
    DYNAMIC = 3
    STATIC  = 4
}

$PROCESS_ACCESS = psenum $Module PROCESS_ACCESS UInt32 @{
    PROCESS_TERMINATE                 = 0x00000001
    PROCESS_CREATE_THREAD             = 0x00000002
    PROCESS_VM_OPERATION              = 0x00000008
    PROCESS_VM_READ                   = 0x00000010
    PROCESS_VM_WRITE                  = 0x00000020
    PROCESS_DUP_HANDLE                = 0x00000040
    PROCESS_CREATE_PROCESS            = 0x00000080
    PROCESS_SET_QUOTA                 = 0x00000100
    PROCESS_SET_INFORMATION           = 0x00000200
    PROCESS_QUERY_INFORMATION         = 0x00000400
    PROCESS_SUSPEND_RESUME            = 0x00000800
    PROCESS_QUERY_LIMITED_INFORMATION = 0x00001000
    DELETE                            = 0x00010000
    READ_CONTROL                      = 0x00020000
    WRITE_DAC                         = 0x00040000
    WRITE_OWNER                       = 0x00080000
    SYNCHRONIZE                       = 0x00100000
    PROCESS_ALL_ACCESS                = 0x001f1ffb
} -Bitfield

$SC_SERVICE_TAG_QUERY_TYPE = psenum $Module SC_SERVICE_TAG_QUERY_TYPE UInt16 @{
    ServiceNameFromTagInformation = 1
    ServiceNamesReferencingModuleInformation = 2
    ServiceNameTagMappingInformation = 3
}

$SE_GROUP = psenum $Module SE_GROUP UInt32 @{
    DISABLED           = 0x00000000
    MANDATORY          = 0x00000001
    ENABLED_BY_DEFAULT = 0x00000002
    ENABLED            = 0x00000004
    OWNER              = 0x00000008
    USE_FOR_DENY_ONLY  = 0x00000010
    INTEGRITY          = 0x00000020
    INTEGRITY_ENABLED  = 0x00000040
    RESOURCE           = 0x20000000
    LOGON_ID           = 3221225472
} -Bitfield

$SE_PRIVILEGE = psenum $Module SE_PRIVILEGE UInt32 @{
    DISABLED           = 0x00000000
    ENABLED_BY_DEFAULT = 0x00000001
    ENABLED            = 0x00000002
    REMOVED            = 0x00000004
    USED_FOR_ACCESS    = 2147483648
} -Bitfield

$SECPKG_FLAG = psenum $Module SECPKG_FLAG UInt32 @{
    INTEGRITY                = 0x1
    PRIVACY                  = 0x2
    TOKEN_ONLY               = 0x4
    DATAGRAM                 = 0x8
    CONNECTION               = 0x10
    MULTI_REQUIRED           = 0x20
    CLIENT_ONLY              = 0x40
    EXTENDED_ERROR           = 0x80
    IMPERSONATION            = 0x100
    ACCEPT_WIN32_NAME        = 0x200
    STREAM                   = 0x400
    NEGOTIABLE               = 0X800
    GSS_COMPATIBLE           = 0x1000
    LOGON                    = 0x2000
    ASCII_BUFFERS            = 0x4000
    FRAGMENT                 = 0x8000
    MUTUAL_AUTH              = 0x10000
    DELEGATION               = 0x20000
    READONLY_WITH_CHECKSUM   = 0x40000
    RESTRICTED_TOKENS        = 0x80000
    NEGO_EXTENDER            = 0x00100000
    NEGOTIABLE2              = 0x00200000
    APPCONTAINER_PASSTHROUGH = 0x00400000
    APPCONTAINER_CHECKS      = 0x00800000

    #SECPKG_CALLFLAGS_APPCONTAINER = 0x00000001
    #SECPKG_CALLFLAGS_AUTHCAPABLE = 0x00000002
    #SECPKG_CALLFLAGS_FORCE_SUPPLIED = 0x00000004
} -Bitfield

$SECURITY_IMPERSONATION_LEVEL = psenum $Module SECURITY_IMPERSONATION_LEVEL UInt32 @{
    SecurityAnonymous      = 0
    SecurityIdentification = 1
    SecurityImpersonation  = 2
    SecurityDelegation     = 3
}

$SECURITY_LOGON_TYPE = psenum $Module SECURITY_LOGON_TYPE UInt32 @{
    Interactive = 2
    Network     = 3
    Batch       = 4
    Service     = 5
    Proxy       = 6
    Unlock      = 7
    NetworkCleartext = 8
    NewCredentials = 9
    RemoteInteractive = 10
    CachedInteractive = 11
    CachedRemoteInteractive = 12
    CachedUnlock = 13
}

$TAG_INFO_LEVEL = psenum $Module TAG_INFO_LEVEL UInt16 @{
    eTagInfoLevelNameFromTag = 1
    eTagInfoLevelNamesReferencingModule = 2
    eTagInfoLevelNameTagMapping = 3
    eTagInfoLevelMax = 4
}

$TCP_STATE = psenum $Module TCP_STATE UInt16 @{
    CLOSED = 1
    LISTENING = 2
    SYN_SENT = 3
    SYN_RECEIVED = 4
    ESTABLISHED = 5
    FIN_WAIT1 = 6
    FIN_WAIT2 = 7
    CLOSE_WAIT = 8
    CLOSING = 9
    LAST_ACK = 10
    TIME_WAIT = 11
    DELETE_TCB = 12
}

$TCP_TABLE_CLASS = psenum $Module TCP_TABLE_CLASS UInt16 @{
    TCP_TABLE_BASIC_LISTENER = 0
    TCP_TABLE_BASIC_CONNECTIONS = 1
    TCP_TABLE_BASIC_ALL = 2
    TCP_TABLE_OWNER_PID_LISTENER = 3
    TCP_TABLE_OWNER_PID_CONNECTIONS = 4
    TCP_TABLE_OWNER_PID_ALL = 5
    TCP_TABLE_OWNER_MODULE_LISTENER = 6
    TCP_TABLE_OWNER_MODULE_CONNECTIONS = 7
    TCP_TABLE_OWNER_MODULE_ALL = 8
}

$TH32CS = psenum $Module TH32CS UInt32 @{
    SNAPHEAPLIST = 0x00000001
    SNAPPROCESS  = 0x00000002
    SNAPTHREAD   = 0x00000004
    SNAPMODULE   = 0x00000008
    SNAPALL      = 0x0000000F
    SNAPMODULE32 = 0x00000010
    INHERIT      = 2147483648
} -Bitfield

$THREAD_ACCESS = psenum $Module THREAD_ACCESS UInt32 @{
    THREAD_TERMINATE                 = 0x00000001
    THREAD_SUSPEND_RESUME            = 0x00000002
    THREAD_GET_CONTEXT               = 0x00000008
    THREAD_SET_CONTEXT               = 0x00000010
    THREAD_SET_INFORMATION           = 0x00000020
    THREAD_QUERY_INFORMATION         = 0x00000040
    THREAD_SET_THREAD_TOKEN          = 0x00000080
    THREAD_IMPERSONATE               = 0x00000100
    THREAD_DIRECT_IMPERSONATION      = 0x00000200
    THREAD_SET_LIMITED_INFORMATION   = 0x00000400
    THREAD_QUERY_LIMITED_INFORMATION = 0x00000800
    DELETE                           = 0x00010000
    READ_CONTROL                     = 0x00020000
    WRITE_DAC                        = 0x00040000
    WRITE_OWNER                      = 0x00080000
    SYNCHRONIZE                      = 0x00100000
    THREAD_ALL_ACCESS                = 0x001f0ffb
} -Bitfield

$THREADINFOCLASS = psenum $Module THREADINFOCLASS UInt32 @{
	ThreadBasicInformation          = 0x00
	ThreadTimes                     = 0x01
	ThreadPriority                  = 0x02
	ThreadBasePriority              = 0x03
	ThreadAffinityMask              = 0x04
	ThreadImpersonationToken        = 0x05
	ThreadDescriptorTableEntry      = 0x06
	ThreadEnableAlignmentFaultFixup = 0x07
	ThreadEventPair_Reusable        = 0x08
	ThreadQuerySetWin32StartAddress = 0x09
	ThreadZeroTlsCell               = 0x0A
	ThreadPerformanceCount          = 0x0B
	ThreadAmILastThread             = 0x0C
	ThreadIdealProcessor            = 0x0D
	ThreadPriorityBoost             = 0x0E
	ThreadSetTlsArrayAddress        = 0x0F
	ThreadIsIoPending               = 0x10
	MaxThreadInfoClass              = 0x11
}

$TOKEN_ACCESS = psenum $Module TOKEN_ACCESS UInt32 @{
    TOKEN_DUPLICATE          = 0x00000002
    TOKEN_IMPERSONATE        = 0x00000004
    TOKEN_QUERY              = 0x00000008
    TOKEN_QUERY_SOURCE       = 0x00000010
    TOKEN_ADJUST_PRIVILEGES  = 0x00000020
    TOKEN_ADJUST_GROUPS      = 0x00000040
    TOKEN_ADJUST_DEFAULT     = 0x00000080
    TOKEN_ADJUST_SESSIONID   = 0x00000100
    DELETE                   = 0x00010000
    READ_CONTROL             = 0x00020000
    WRITE_DAC                = 0x00040000
    WRITE_OWNER              = 0x00080000
    SYNCHRONIZE              = 0x00100000
    STANDARD_RIGHTS_REQUIRED = 0x000F0000
    TOKEN_ALL_ACCESS         = 0x001f01ff
} -Bitfield

$TOKEN_ELEVATION_TYPE = psenum $Module TOKEN_ELEVATION_TYPE UInt32 @{ 
    TokenElevationTypeDefault = 1
    TokenElevationTypeFull    = 2
    TokenElevationTypeLimited = 3
}

$TOKEN_INFORMATION_CLASS = psenum $Module TOKEN_INFORMATION_CLASS UInt16 @{ 
    TokenUser                            = 1
    TokenGroups                          = 2
    TokenPrivileges                      = 3
    TokenOwner                           = 4
    TokenPrimaryGroup                    = 5
    TokenDefaultDacl                     = 6
    TokenSource                          = 7
    TokenType                            = 8
    TokenImpersonationLevel              = 9
    TokenStatistics                      = 10
    TokenRestrictedSids                  = 11
    TokenSessionId                       = 12
    TokenGroupsAndPrivileges             = 13
    TokenSessionReference                = 14
    TokenSandBoxInert                    = 15
    TokenAuditPolicy                     = 16
    TokenOrigin                          = 17
    TokenElevationType                   = 18
    TokenLinkedToken                     = 19
    TokenElevation                       = 20
    TokenHasRestrictions                 = 21
    TokenAccessInformation               = 22
    TokenVirtualizationAllowed           = 23
    TokenVirtualizationEnabled           = 24
    TokenIntegrityLevel                  = 25
    TokenUIAccess                        = 26
    TokenMandatoryPolicy                 = 27
    TokenLogonSid                        = 28
    TokenIsAppContainer                  = 29
    TokenCapabilities                    = 30
    TokenAppContainerSid                 = 31
    TokenAppContainerNumber              = 32
    TokenUserClaimAttributes             = 33
    TokenDeviceClaimAttributes           = 34
    TokenRestrictedUserClaimAttributes   = 35
    TokenRestrictedDeviceClaimAttributes = 36
    TokenDeviceGroups                    = 37
    To
Download .txt
gitextract_n0h_95a4/

├── ACE-Docker/
│   ├── README.md
│   ├── ace-ca/
│   │   └── dockerfile
│   ├── ace-nginx/
│   │   ├── Dockerfile
│   │   ├── README.md
│   │   ├── entrypoint.sh
│   │   └── nginx.conf
│   ├── ace-rabbitmq/
│   │   ├── Dockerfile
│   │   ├── README.md
│   │   ├── ace-cache.py
│   │   ├── ace-entrypoint.sh
│   │   └── ace-lookup.py
│   ├── ace-sql/
│   │   ├── Dockerfile
│   │   ├── README.md
│   │   ├── ace.sql
│   │   └── import-data.sh
│   ├── ace.env
│   ├── docker-compose.yml
│   ├── settings.sh
│   └── start.sh
├── ACE-Management/
│   └── PS-ACE/
│       ├── Cmdlets/
│       │   ├── Download-AceFile.ps1
│       │   ├── Get-AceComputer.ps1
│       │   ├── Get-AceCredential.ps1
│       │   ├── Get-AceSchedule.ps1
│       │   ├── Get-AceScript.ps1
│       │   ├── Get-AceSweep.ps1
│       │   ├── Get-AceSweepResult.ps1
│       │   ├── Get-AceUser.ps1
│       │   ├── Invoke-AceWebRequest.ps1
│       │   ├── New-AceCredential.ps1
│       │   ├── New-AceScheduledScan.ps1
│       │   ├── New-AceScript.ps1
│       │   ├── New-AceUser.ps1
│       │   ├── Remove-AceCredential.ps1
│       │   ├── Remove-AceScript.ps1
│       │   ├── Remove-AceUser.ps1
│       │   ├── Send-AceResult.ps1
│       │   ├── Start-AceDiscovery.ps1
│       │   ├── Start-AceSweep.ps1
│       │   ├── Update-AceCredential.ps1
│       │   └── Update-AceUser.ps1
│       ├── PS-ACE.psm1
│       ├── README.md
│       ├── Scripts/
│       │   ├── ACE-Master.ps1
│       │   ├── ACE_Get-AccessToken.ps1
│       │   ├── ACE_Get-ArpCache.ps1
│       │   ├── ACE_Get-Atom.ps1
│       │   ├── ACE_Get-InjectedThread.ps1
│       │   ├── ACE_Get-KerberosTicketCache.ps1
│       │   ├── ACE_Get-LogonSession.ps1
│       │   ├── ACE_Get-MasterBootRecord.ps1
│       │   ├── ACE_Get-NetworkConnection.ps1
│       │   ├── ACE_Get-PSAutorun.ps1
│       │   ├── ACE_Get-PSIProcess.ps1
│       │   ├── ACE_Get-PSIScheduledTask.ps1
│       │   ├── ACE_Get-PSIService.ps1
│       │   ├── ACE_Get-PSIWindowsSecurityEvent.ps1
│       │   ├── ACE_Get-ScheduledJob.ps1
│       │   ├── ACE_Get-SecurityPackage.ps1
│       │   ├── ACE_Get-SimpleNamedPipe.ps1
│       │   └── Invoke-MonsterWinRM.ps1
│       └── Working/
│           └── ACE_Get-PSIPrefetch.ps1
├── ACE-WebService/
│   ├── .gitignore
│   ├── ACEWebService.sln
│   ├── Configure-AceWebService.ps1
│   ├── NuGet.config
│   ├── dockerfile
│   └── src/
│       └── ACEWebService/
│           ├── ACEWebService.csproj
│           ├── App.config
│           ├── AppSettings.cs
│           ├── Controllers/
│           │   ├── ComputerController.cs
│           │   ├── CredentialController.cs
│           │   ├── DiscoverController.cs
│           │   ├── DownloadController.cs
│           │   ├── ResultController.cs
│           │   ├── ScanController.cs
│           │   ├── ScriptController.cs
│           │   ├── SweepController.cs
│           │   └── UserController.cs
│           ├── DbModelBuilder.cs
│           ├── Entities/
│           │   ├── ACEWebServiceDbContext.cs
│           │   ├── Computer.cs
│           │   ├── ComputerGroup.cs
│           │   ├── Credential.cs
│           │   ├── Download.cs
│           │   ├── Scan.cs
│           │   ├── Schedule.cs
│           │   ├── Script.cs
│           │   ├── Sweep.cs
│           │   └── User.cs
│           ├── Migrations/
│           │   ├── 20170322221439_MyFirstMigration.Designer.cs
│           │   ├── 20170322221439_MyFirstMigration.cs
│           │   ├── 20170322222622_MySecondMigration.Designer.cs
│           │   ├── 20170322222622_MySecondMigration.cs
│           │   ├── 20170417201050_MyThirdMigration.Designer.cs
│           │   ├── 20170417201050_MyThirdMigration.cs
│           │   ├── 20170420231736_MyFourthMigration.Designer.cs
│           │   ├── 20170420231736_MyFourthMigration.cs
│           │   ├── 20170421030619_MyFifthMigration.Designer.cs
│           │   ├── 20170421030619_MyFifthMigration.cs
│           │   ├── 20170429215921_MySixthMigration.Designer.cs
│           │   ├── 20170429215921_MySixthMigration.cs
│           │   ├── 20170430141205_MySeventhMigration.Designer.cs
│           │   ├── 20170430141205_MySeventhMigration.cs
│           │   ├── 20170707032113_MyEigthMigration.Designer.cs
│           │   ├── 20170707032113_MyEigthMigration.cs
│           │   ├── 20170707040959_MyNinthMigration.Designer.cs
│           │   ├── 20170707040959_MyNinthMigration.cs
│           │   ├── 20170707042221_MyTenthMigration.Designer.cs
│           │   ├── 20170707042221_MyTenthMigration.cs
│           │   ├── 20170713053904_MyEleventhMigration.Designer.cs
│           │   ├── 20170713053904_MyEleventhMigration.cs
│           │   ├── 20171116210534_MyTwelfthMigration.Designer.cs
│           │   ├── 20171116210534_MyTwelfthMigration.cs
│           │   ├── 20171116211023_MyThirteenthMigration.Designer.cs
│           │   ├── 20171116211023_MyThirteenthMigration.cs
│           │   ├── 20171116233431_MyFourteenthMigration.Designer.cs
│           │   ├── 20171116233431_MyFourteenthMigration.cs
│           │   └── ACEWebServiceDbContextModelSnapshot.cs
│           ├── Program.cs
│           ├── Project_Readme.html
│           ├── Properties/
│           │   ├── PublishProfiles/
│           │   │   ├── ACEWebService-publish.ps1
│           │   │   ├── ACEWebService.pubxml
│           │   │   ├── FileSystem-publish.ps1
│           │   │   ├── FileSystem.pubxml
│           │   │   └── publish-module.psm1
│           │   └── launchSettings.json
│           ├── Security/
│           │   ├── ApiKeyPolicy.cs
│           │   └── IsAdminPolicy.cs
│           ├── Services/
│           │   ├── IAceConfiguration.cs
│           │   ├── ICryptographyService.cs
│           │   ├── IDiscoveryService.cs
│           │   ├── IDownloadService.cs
│           │   ├── ISweepExecutionService.cs
│           │   └── ISweepResultProcessorService.cs
│           ├── Startup.cs
│           ├── ViewModels/
│           │   ├── ArbitrarySweepViewModel.cs
│           │   ├── CredentialViewModel.cs
│           │   ├── DiscoveryActiveDirectoryViewModel.cs
│           │   ├── DiscoveryComputerListViewModel.cs
│           │   ├── DownloadReceiveViewModel.cs
│           │   ├── DownloadRequestViewModel.cs
│           │   ├── ErrorViewModel.cs
│           │   ├── FileViewModel.cs
│           │   ├── ScheduleIntervalViewModel.cs
│           │   ├── ScheduleTimeViewModel.cs
│           │   ├── SweepExecutionViewModel.cs
│           │   ├── SweepResultViewModel.cs
│           │   └── UserViewModel.cs
│           ├── appsettings.Production.json
│           ├── appsettings.json
│           ├── nuget.config
│           ├── scripts/
│           │   ├── Download-AceFile.ps1
│           │   └── Start-AceScript.ps1
│           └── web.config
├── LICENSE-Quartz.NET
├── LICENSE-RabbitMQ
├── LICENSE-SSH.NET
├── LICENSE-osxcollector
└── README.md
Download .txt
SYMBOL INDEX (216 symbols across 76 files)

FILE: ACE-Docker/ace-rabbitmq/ace-cache.py
  class CachedConsumer (line 13) | class CachedConsumer(object):
    method __init__ (line 21) | def __init__(self, connection):
    method consume_message (line 29) | def consume_message(self, channel, method, properties, body):
    method publish_message (line 65) | def publish_message(self, method, message, routingKey):
  function main (line 73) | def main():

FILE: ACE-Docker/ace-rabbitmq/ace-lookup.py
  class VTConsumer (line 9) | class VTConsumer(object):
    method __init__ (line 17) | def __init__(self, api_key, connection):
    method consume_message (line 27) | def consume_message(self, channel, method, properties, body):
    method lookup_hash (line 45) | def lookup_hash(self, sha256hash):
    method publish_message (line 69) | def publish_message(self, method, message):
  function main (line 78) | def main():

FILE: ACE-Docker/ace-sql/ace.sql
  type dbo (line 1) | CREATE TABLE [dbo].[Credentials] (
  type IX_Computers_CredentialId (line 23) | CREATE NONCLUSTERED INDEX [IX_Computers_CredentialId]
  type dbo (line 26) | CREATE TABLE [dbo].[Scans] (
  type dbo (line 37) | CREATE TABLE [dbo].[Scripts] (
  type dbo (line 58) | CREATE TABLE [dbo].[Schedules] (

FILE: ACE-WebService/src/ACEWebService/AppSettings.cs
  class AppSettings (line 8) | public class AppSettings

FILE: ACE-WebService/src/ACEWebService/Controllers/ComputerController.cs
  class ComputerController (line 10) | [Authorize(Policy = "ApiKey")]
    method ComputerController (line 16) | public ComputerController(ACEWebServiceDbContext context)
    method Get (line 21) | [HttpGet("{id}")]
    method Get (line 30) | [HttpGet()]

FILE: ACE-WebService/src/ACEWebService/Controllers/CredentialController.cs
  class CredentialController (line 13) | [Authorize(Policy = "ApiKey")]
    method CredentialController (line 20) | public CredentialController(ACEWebServiceDbContext context, ICryptogra...
    method Delete (line 27) | [HttpGet("delete/{id}")]
    method Get (line 53) | [HttpGet()]
    method Get (line 69) | [HttpGet("pscredential/{id}")]
    method Post (line 88) | [HttpPost()]
    method Update (line 118) | [HttpPut("{id}")]

FILE: ACE-WebService/src/ACEWebService/Controllers/DiscoverController.cs
  class DiscoverController (line 9) | [Authorize(Policy = "ApiKey")]
    method DiscoverController (line 15) | public DiscoverController(IDiscoveryService discoverService)
    method ComputerList (line 39) | [Route("/ace/discover/computerlist")]

FILE: ACE-WebService/src/ACEWebService/Controllers/DownloadController.cs
  class DownloadController (line 11) | [Route("ace/[controller]")]
    method DownloadController (line 18) | public DownloadController(ACEWebServiceDbContext context, IHostingEnvi...
    method RequestFile (line 26) | [Authorize(Policy = "ApiKey")]
    method ReceiveFile (line 43) | [HttpPost("{id}")]

FILE: ACE-WebService/src/ACEWebService/Controllers/ResultController.cs
  class ResultController (line 9) | [Route("ace/[controller]")]
    method ResultController (line 15) | public ResultController(ISweepResultProcessorService sweepWriterService)
    method Post (line 21) | [HttpPost("{id}")]

FILE: ACE-WebService/src/ACEWebService/Controllers/ScanController.cs
  class ScanController (line 9) | [Authorize(Policy = "ApiKey")]
    method ScanController (line 15) | public ScanController(ACEWebServiceDbContext context)
    method GetSweepScans (line 21) | [HttpGet("{id}")]
    method Success (line 28) | [Route("/ace/scan/success/{id}")]
    method Failure (line 58) | [Route("/ace/scan/failed/{id}")]

FILE: ACE-WebService/src/ACEWebService/Controllers/ScriptController.cs
  class ScriptController (line 17) | [Route("ace/[controller]")]
    method ScriptController (line 23) | public ScriptController(ACEWebServiceDbContext context, IHostingEnviro...
    method Delete (line 30) | [HttpGet("delete/{id}")]
    method Get (line 62) | [HttpGet]
    method Upload (line 69) | [HttpPost]

FILE: ACE-WebService/src/ACEWebService/Controllers/SweepController.cs
  class SweepController (line 12) | [Authorize(Policy = "ApiKey")]
    method SweepController (line 19) | public SweepController(ISweepExecutionService sweepExecutionService, A...
    method Get (line 26) | [HttpGet()]
    method Get (line 33) | [HttpGet("{id}")]
    method Post (line 41) | [HttpPost]
    method Put (line 57) | [AllowAnonymous]

FILE: ACE-WebService/src/ACEWebService/Controllers/UserController.cs
  class UserController (line 11) | [Authorize(Policy = "ApiKey")]
    method UserController (line 17) | public UserController(ACEWebServiceDbContext context)
    method Delete (line 23) | [HttpGet("delete/{id}")]
    method Get (line 56) | [HttpGet]
    method Post (line 74) | [HttpPost]
    method Update (line 107) | [HttpPut("{Id}")]

FILE: ACE-WebService/src/ACEWebService/DbModelBuilder.cs
  class DbModelBuilder (line 5) | internal class DbModelBuilder
    method Entity (line 7) | internal object Entity<T>()

FILE: ACE-WebService/src/ACEWebService/Entities/ACEWebServiceDbContext.cs
  class ACEWebServiceDbContext (line 6) | public class ACEWebServiceDbContext : DbContext
    method ACEWebServiceDbContext (line 8) | public ACEWebServiceDbContext(DbContextOptions<ACEWebServiceDbContext>...

FILE: ACE-WebService/src/ACEWebService/Entities/Computer.cs
  class Computer (line 7) | public class Computer

FILE: ACE-WebService/src/ACEWebService/Entities/ComputerGroup.cs
  class ComputerGroup (line 8) | public class ComputerGroup

FILE: ACE-WebService/src/ACEWebService/Entities/Credential.cs
  class Credential (line 7) | public class Credential

FILE: ACE-WebService/src/ACEWebService/Entities/Download.cs
  class Download (line 7) | public class Download

FILE: ACE-WebService/src/ACEWebService/Entities/Scan.cs
  class Scan (line 7) | public class Scan

FILE: ACE-WebService/src/ACEWebService/Entities/Schedule.cs
  class Schedule (line 7) | public class Schedule

FILE: ACE-WebService/src/ACEWebService/Entities/Script.cs
  class Script (line 7) | public class Script

FILE: ACE-WebService/src/ACEWebService/Entities/Sweep.cs
  class Sweep (line 8) | public class Sweep

FILE: ACE-WebService/src/ACEWebService/Entities/User.cs
  class User (line 7) | public class User

FILE: ACE-WebService/src/ACEWebService/Migrations/20170322221439_MyFirstMigration.Designer.cs
  class MyFirstMigration (line 10) | [DbContext(typeof(ACEWebServiceDbContext))]
    method BuildTargetModel (line 14) | protected override void BuildTargetModel(ModelBuilder modelBuilder)

FILE: ACE-WebService/src/ACEWebService/Migrations/20170322221439_MyFirstMigration.cs
  class MyFirstMigration (line 7) | public partial class MyFirstMigration : Migration
    method Up (line 9) | protected override void Up(MigrationBuilder migrationBuilder)
    method Down (line 128) | protected override void Down(MigrationBuilder migrationBuilder)

FILE: ACE-WebService/src/ACEWebService/Migrations/20170322222622_MySecondMigration.Designer.cs
  class MySecondMigration (line 10) | [DbContext(typeof(ACEWebServiceDbContext))]
    method BuildTargetModel (line 14) | protected override void BuildTargetModel(ModelBuilder modelBuilder)

FILE: ACE-WebService/src/ACEWebService/Migrations/20170322222622_MySecondMigration.cs
  class MySecondMigration (line 7) | public partial class MySecondMigration : Migration
    method Up (line 9) | protected override void Up(MigrationBuilder migrationBuilder)
    method Down (line 30) | protected override void Down(MigrationBuilder migrationBuilder)

FILE: ACE-WebService/src/ACEWebService/Migrations/20170417201050_MyThirdMigration.Designer.cs
  class MyThirdMigration (line 10) | [DbContext(typeof(ACEWebServiceDbContext))]
    method BuildTargetModel (line 14) | protected override void BuildTargetModel(ModelBuilder modelBuilder)

FILE: ACE-WebService/src/ACEWebService/Migrations/20170417201050_MyThirdMigration.cs
  class MyThirdMigration (line 7) | public partial class MyThirdMigration : Migration
    method Up (line 9) | protected override void Up(MigrationBuilder migrationBuilder)
    method Down (line 14) | protected override void Down(MigrationBuilder migrationBuilder)

FILE: ACE-WebService/src/ACEWebService/Migrations/20170420231736_MyFourthMigration.Designer.cs
  class MyFourthMigration (line 10) | [DbContext(typeof(ACEWebServiceDbContext))]
    method BuildTargetModel (line 14) | protected override void BuildTargetModel(ModelBuilder modelBuilder)

FILE: ACE-WebService/src/ACEWebService/Migrations/20170420231736_MyFourthMigration.cs
  class MyFourthMigration (line 7) | public partial class MyFourthMigration : Migration
    method Up (line 9) | protected override void Up(MigrationBuilder migrationBuilder)
    method Down (line 18) | protected override void Down(MigrationBuilder migrationBuilder)

FILE: ACE-WebService/src/ACEWebService/Migrations/20170421030619_MyFifthMigration.Designer.cs
  class MyFifthMigration (line 10) | [DbContext(typeof(ACEWebServiceDbContext))]
    method BuildTargetModel (line 14) | protected override void BuildTargetModel(ModelBuilder modelBuilder)

FILE: ACE-WebService/src/ACEWebService/Migrations/20170421030619_MyFifthMigration.cs
  class MyFifthMigration (line 7) | public partial class MyFifthMigration : Migration
    method Up (line 9) | protected override void Up(MigrationBuilder migrationBuilder)
    method Down (line 18) | protected override void Down(MigrationBuilder migrationBuilder)

FILE: ACE-WebService/src/ACEWebService/Migrations/20170429215921_MySixthMigration.Designer.cs
  class MySixthMigration (line 10) | [DbContext(typeof(ACEWebServiceDbContext))]
    method BuildTargetModel (line 14) | protected override void BuildTargetModel(ModelBuilder modelBuilder)

FILE: ACE-WebService/src/ACEWebService/Migrations/20170429215921_MySixthMigration.cs
  class MySixthMigration (line 7) | public partial class MySixthMigration : Migration
    method Up (line 9) | protected override void Up(MigrationBuilder migrationBuilder)
    method Down (line 45) | protected override void Down(MigrationBuilder migrationBuilder)

FILE: ACE-WebService/src/ACEWebService/Migrations/20170430141205_MySeventhMigration.Designer.cs
  class MySeventhMigration (line 10) | [DbContext(typeof(ACEWebServiceDbContext))]
    method BuildTargetModel (line 14) | protected override void BuildTargetModel(ModelBuilder modelBuilder)

FILE: ACE-WebService/src/ACEWebService/Migrations/20170430141205_MySeventhMigration.cs
  class MySeventhMigration (line 7) | public partial class MySeventhMigration : Migration
    method Up (line 9) | protected override void Up(MigrationBuilder migrationBuilder)
    method Down (line 30) | protected override void Down(MigrationBuilder migrationBuilder)

FILE: ACE-WebService/src/ACEWebService/Migrations/20170707032113_MyEigthMigration.Designer.cs
  class MyEigthMigration (line 10) | [DbContext(typeof(ACEWebServiceDbContext))]
    method BuildTargetModel (line 14) | protected override void BuildTargetModel(ModelBuilder modelBuilder)

FILE: ACE-WebService/src/ACEWebService/Migrations/20170707032113_MyEigthMigration.cs
  class MyEigthMigration (line 7) | public partial class MyEigthMigration : Migration
    method Up (line 9) | protected override void Up(MigrationBuilder migrationBuilder)
    method Down (line 22) | protected override void Down(MigrationBuilder migrationBuilder)

FILE: ACE-WebService/src/ACEWebService/Migrations/20170707040959_MyNinthMigration.Designer.cs
  class MyNinthMigration (line 10) | [DbContext(typeof(ACEWebServiceDbContext))]
    method BuildTargetModel (line 14) | protected override void BuildTargetModel(ModelBuilder modelBuilder)

FILE: ACE-WebService/src/ACEWebService/Migrations/20170707040959_MyNinthMigration.cs
  class MyNinthMigration (line 7) | public partial class MyNinthMigration : Migration
    method Up (line 9) | protected override void Up(MigrationBuilder migrationBuilder)
    method Down (line 25) | protected override void Down(MigrationBuilder migrationBuilder)

FILE: ACE-WebService/src/ACEWebService/Migrations/20170707042221_MyTenthMigration.Designer.cs
  class MyTenthMigration (line 10) | [DbContext(typeof(ACEWebServiceDbContext))]
    method BuildTargetModel (line 14) | protected override void BuildTargetModel(ModelBuilder modelBuilder)

FILE: ACE-WebService/src/ACEWebService/Migrations/20170707042221_MyTenthMigration.cs
  class MyTenthMigration (line 7) | public partial class MyTenthMigration : Migration
    method Up (line 9) | protected override void Up(MigrationBuilder migrationBuilder)
    method Down (line 18) | protected override void Down(MigrationBuilder migrationBuilder)

FILE: ACE-WebService/src/ACEWebService/Migrations/20170713053904_MyEleventhMigration.Designer.cs
  class MyEleventhMigration (line 10) | [DbContext(typeof(ACEWebServiceDbContext))]
    method BuildTargetModel (line 14) | protected override void BuildTargetModel(ModelBuilder modelBuilder)

FILE: ACE-WebService/src/ACEWebService/Migrations/20170713053904_MyEleventhMigration.cs
  class MyEleventhMigration (line 7) | public partial class MyEleventhMigration : Migration
    method Up (line 9) | protected override void Up(MigrationBuilder migrationBuilder)
    method Down (line 24) | protected override void Down(MigrationBuilder migrationBuilder)

FILE: ACE-WebService/src/ACEWebService/Migrations/20171116210534_MyTwelfthMigration.Designer.cs
  class MyTwelfthMigration (line 10) | [DbContext(typeof(ACEWebServiceDbContext))]
    method BuildTargetModel (line 14) | protected override void BuildTargetModel(ModelBuilder modelBuilder)

FILE: ACE-WebService/src/ACEWebService/Migrations/20171116210534_MyTwelfthMigration.cs
  class MyTwelfthMigration (line 7) | public partial class MyTwelfthMigration : Migration
    method Up (line 9) | protected override void Up(MigrationBuilder migrationBuilder)
    method Down (line 30) | protected override void Down(MigrationBuilder migrationBuilder)

FILE: ACE-WebService/src/ACEWebService/Migrations/20171116211023_MyThirteenthMigration.Designer.cs
  class MyThirteenthMigration (line 10) | [DbContext(typeof(ACEWebServiceDbContext))]
    method BuildTargetModel (line 14) | protected override void BuildTargetModel(ModelBuilder modelBuilder)

FILE: ACE-WebService/src/ACEWebService/Migrations/20171116211023_MyThirteenthMigration.cs
  class MyThirteenthMigration (line 7) | public partial class MyThirteenthMigration : Migration
    method Up (line 9) | protected override void Up(MigrationBuilder migrationBuilder)
    method Down (line 38) | protected override void Down(MigrationBuilder migrationBuilder)

FILE: ACE-WebService/src/ACEWebService/Migrations/20171116233431_MyFourteenthMigration.Designer.cs
  class MyFourteenthMigration (line 10) | [DbContext(typeof(ACEWebServiceDbContext))]
    method BuildTargetModel (line 14) | protected override void BuildTargetModel(ModelBuilder modelBuilder)

FILE: ACE-WebService/src/ACEWebService/Migrations/20171116233431_MyFourteenthMigration.cs
  class MyFourteenthMigration (line 7) | public partial class MyFourteenthMigration : Migration
    method Up (line 9) | protected override void Up(MigrationBuilder migrationBuilder)
    method Down (line 18) | protected override void Down(MigrationBuilder migrationBuilder)

FILE: ACE-WebService/src/ACEWebService/Migrations/ACEWebServiceDbContextModelSnapshot.cs
  class ACEWebServiceDbContextModelSnapshot (line 10) | [DbContext(typeof(ACEWebServiceDbContext))]
    method BuildModel (line 13) | protected override void BuildModel(ModelBuilder modelBuilder)

FILE: ACE-WebService/src/ACEWebService/Program.cs
  class Program (line 7) | public class Program
    method Main (line 9) | public static void Main(string[] args)

FILE: ACE-WebService/src/ACEWebService/Security/ApiKeyPolicy.cs
  class ApiKeyRequirement (line 10) | public class ApiKeyRequirement : IAuthorizationRequirement
    method ApiKeyRequirement (line 12) | public ApiKeyRequirement()
  class ApiKeyHandler (line 18) | public class ApiKeyHandler : AuthorizationHandler<ApiKeyRequirement>
    method ApiKeyHandler (line 22) | public ApiKeyHandler(ACEWebServiceDbContext context)
    method HandleRequirementAsync (line 27) | protected override Task HandleRequirementAsync(AuthorizationHandlerCon...

FILE: ACE-WebService/src/ACEWebService/Security/IsAdminPolicy.cs
  class IsAdminRequirement (line 9) | public class IsAdminRequirement : IAuthorizationRequirement
    method IsAdminRequirement (line 11) | public IsAdminRequirement()
  class IsAdminHandler (line 17) | public class IsAdminHandler : AuthorizationHandler<ApiKeyRequirement>
    method IsAdminHandler (line 21) | public IsAdminHandler(ACEWebServiceDbContext context)
    method HandleRequirementAsync (line 26) | protected override Task HandleRequirementAsync(AuthorizationHandlerCon...

FILE: ACE-WebService/src/ACEWebService/Services/IAceConfiguration.cs
  type IAceConfiguration (line 5) | public interface IAceConfiguration
  class AceConfiguration (line 10) | public class AceConfiguration : IAceConfiguration
    method AceConfiguration (line 14) | public AceConfiguration(IConfigurationRoot configuration)

FILE: ACE-WebService/src/ACEWebService/Services/ICryptographyService.cs
  type ICryptographyService (line 5) | public interface ICryptographyService
    method Encrypt (line 7) | string Encrypt(string clearText);
    method Decrypt (line 8) | string Decrypt(string cipherText);
  class AESCryptographyService (line 11) | public class AESCryptographyService : ICryptographyService
    method AESCryptographyService (line 15) | public AESCryptographyService(IDataProtectionProvider provider)
    method Encrypt (line 20) | public string Encrypt(string plaintext)
    method Decrypt (line 25) | public string Decrypt(string encryptedText)

FILE: ACE-WebService/src/ACEWebService/Services/IDiscoveryService.cs
  type IDiscoveryService (line 15) | public interface IDiscoveryService
    method Discover (line 18) | void Discover(DiscoveryComputerListViewModel param);
  class DiscoveryActiveDirectoryService (line 21) | public class DiscoveryActiveDirectoryService : IDiscoveryService
    method DiscoveryActiveDirectoryService (line 27) | public DiscoveryActiveDirectoryService(ACEWebServiceDbContext context,...
    method Discover (line 159) | public void Discover(DiscoveryComputerListViewModel param)
    method CreateTask (line 201) | private static Task CreateTask(BlockingCollection<Wrapper<ACEComputer>...
    method GetComputer (line 250) | private Computer GetComputer(string computername, string operatingsyst...
    method TestPort (line 266) | internal static bool TestPort(string hostname, int port)
  class ACEComputer (line 290) | internal class ACEComputer

FILE: ACE-WebService/src/ACEWebService/Services/IDownloadService.cs
  type IDownloadService (line 13) | public interface IDownloadService
    method DownloadRequest (line 15) | void DownloadRequest(DownloadRequestViewModel param, Guid Id);
  class DownloadService (line 18) | public class DownloadService : IDownloadService
    method DownloadService (line 24) | public DownloadService(ACEWebServiceDbContext context, ICryptographySe...
    method DownloadRequest (line 31) | public void DownloadRequest(DownloadRequestViewModel param, Guid Id)
    method KickOffCim (line 80) | private void KickOffCim(Computer computer, Credential credential, stri...

FILE: ACE-WebService/src/ACEWebService/Services/ISweepExecutionService.cs
  type ISweepExecutionService (line 20) | public interface ISweepExecutionService
    method Sweep (line 22) | Guid Sweep(SweepExecutionViewModel param);
  class SweepExecutionService (line 25) | public class SweepExecutionService : ISweepExecutionService
    method SweepExecutionService (line 31) | public SweepExecutionService(ACEWebServiceDbContext context, ICryptogr...
    method Sweep (line 38) | public Guid Sweep(SweepExecutionViewModel param)
    method CreateTask (line 107) | private Task CreateTask(BlockingCollection<Wrapper<ACETasking>> input)
    method KickOffCimAsync (line 187) | private void KickOffCimAsync(Computer computer, Credential credential,...
    method KickOffSSHAsync (line 230) | private void KickOffSSHAsync(Computer computer, Credential credential,...
  class Wrapper (line 241) | internal class Wrapper<T>
  class ACETasking (line 246) | internal class ACETasking

FILE: ACE-WebService/src/ACEWebService/Services/ISweepResultProcessorService.cs
  type ISweepResultProcessorService (line 10) | public interface ISweepResultProcessorService
    method Process (line 12) | void Process(Guid scanId, SweepResultViewModel scanData);
  class ScanResultRabbitMQService (line 15) | public class ScanResultRabbitMQService : ISweepResultProcessorService
    method ScanResultRabbitMQService (line 19) | public ScanResultRabbitMQService(IOptions<AppSettings> settings)
    method Process (line 24) | public void Process(Guid scanId, SweepResultViewModel sweepData)

FILE: ACE-WebService/src/ACEWebService/Startup.cs
  class Startup (line 26) | public class Startup
    method Startup (line 30) | public Startup(IHostingEnvironment env)
    method ConfigureServices (line 46) | public void ConfigureServices(IServiceCollection services)
    method Configure (line 121) | public void Configure(IApplicationBuilder app, IHostingEnvironment env...
    method GlobalExceptionHandler (line 145) | public void GlobalExceptionHandler(IApplicationBuilder builder)

FILE: ACE-WebService/src/ACEWebService/ViewModels/ArbitrarySweepViewModel.cs
  class ArbitrarySweepViewModel (line 7) | public class ArbitrarySweepViewModel

FILE: ACE-WebService/src/ACEWebService/ViewModels/CredentialViewModel.cs
  class CredentialViewModel (line 5) | public class CredentialViewModel

FILE: ACE-WebService/src/ACEWebService/ViewModels/DiscoveryActiveDirectoryViewModel.cs
  class DiscoveryActiveDirectoryViewModel (line 6) | public class DiscoveryActiveDirectoryViewModel

FILE: ACE-WebService/src/ACEWebService/ViewModels/DiscoveryComputerListViewModel.cs
  class DiscoveryComputerListViewModel (line 6) | public class DiscoveryComputerListViewModel

FILE: ACE-WebService/src/ACEWebService/ViewModels/DownloadReceiveViewModel.cs
  class DownloadReceiveViewModel (line 6) | public class DownloadReceiveViewModel

FILE: ACE-WebService/src/ACEWebService/ViewModels/DownloadRequestViewModel.cs
  class DownloadRequestViewModel (line 6) | public class DownloadRequestViewModel

FILE: ACE-WebService/src/ACEWebService/ViewModels/ErrorViewModel.cs
  class ErrorViewModel (line 5) | public class ErrorViewModel
    method ToString (line 10) | public override string ToString()

FILE: ACE-WebService/src/ACEWebService/ViewModels/FileViewModel.cs
  class FileViewModel (line 5) | public class FileViewModel

FILE: ACE-WebService/src/ACEWebService/ViewModels/ScheduleIntervalViewModel.cs
  class ScheduleIntervalViewModel (line 5) | public class ScheduleIntervalViewModel

FILE: ACE-WebService/src/ACEWebService/ViewModels/ScheduleTimeViewModel.cs
  class ScheduleTimeViewModel (line 7) | public class ScheduleTimeViewModel

FILE: ACE-WebService/src/ACEWebService/ViewModels/SweepExecutionViewModel.cs
  class SweepExecutionViewModel (line 6) | public class SweepExecutionViewModel

FILE: ACE-WebService/src/ACEWebService/ViewModels/SweepResultViewModel.cs
  class SweepResultViewModel (line 7) | public class SweepResultViewModel

FILE: ACE-WebService/src/ACEWebService/ViewModels/UserViewModel.cs
  class UserViewModel (line 5) | public class UserViewModel
Condensed preview — 159 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,326K chars).
[
  {
    "path": "ACE-Docker/README.md",
    "chars": 1610,
    "preview": "# ACE-Docker\nThis project focuses on simplifying ACE's deployment process as much as possible.\n\n## Goals\n\n## Components\n"
  },
  {
    "path": "ACE-Docker/ace-ca/dockerfile",
    "chars": 279,
    "preview": "FROM cfssl/cfssl:latest\n\nRUN cfssl print-defaults config > ca-config.json && cfssl print-defaults csr > ca-csr.json \\  \n"
  },
  {
    "path": "ACE-Docker/ace-nginx/Dockerfile",
    "chars": 301,
    "preview": "FROM nginx\nMAINTAINER Jared Atkinson <jared@invoke-ir.com>\nRUN apt-get update; apt-get install -y openssl\nCOPY ./nginx.c"
  },
  {
    "path": "ACE-Docker/ace-nginx/README.md",
    "chars": 2077,
    "preview": "Built on [nginx](https://hub.docker.com/_/nginx/), this image provides an SSL proxy for the [ACE Web Application](https:"
  },
  {
    "path": "ACE-Docker/ace-nginx/entrypoint.sh",
    "chars": 756,
    "preview": "#!/bin/sh\n\n# Add Environment Variable to nginx.conf\nsed -i -e 's/\\[WEBSERVICE_IP\\]/'\"$WEBSERVICE_IP\"'/g' /etc/nginx/ngin"
  },
  {
    "path": "ACE-Docker/ace-nginx/nginx.conf",
    "chars": 1723,
    "preview": "worker_processes 4;\n\nevents { worker_connections 1024; }\n\nhttp {\n    # Allow files of <= 2MB to be uploaded\n    client_m"
  },
  {
    "path": "ACE-Docker/ace-rabbitmq/Dockerfile",
    "chars": 609,
    "preview": "FROM  rabbitmq:3-management\nMAINTAINER Jared Atkinson <jared@invoke-ir.com>\nADD ace-entrypoint.sh /root/ace-entrypoint.s"
  },
  {
    "path": "ACE-Docker/ace-rabbitmq/README.md",
    "chars": 1275,
    "preview": "Built on [RabbitMQ](https://hub.docker.com/_/rabbitmq/), this images provides the backend database used by the [ACE Rabb"
  },
  {
    "path": "ACE-Docker/ace-rabbitmq/ace-cache.py",
    "chars": 5608,
    "preview": "#!/usr/bin/env python\nimport json\nimport sys\nimport pika\nimport requests\nfrom argparse import ArgumentParser\nfrom json i"
  },
  {
    "path": "ACE-Docker/ace-rabbitmq/ace-entrypoint.sh",
    "chars": 359,
    "preview": "#!/bin/bash\npython /root/ace-lookup.py -s 127.0.0.1 -u $RABBITMQ_DEFAULT_USER -p $RABBITMQ_DEFAULT_PASS -k $APIKEY &\npyt"
  },
  {
    "path": "ACE-Docker/ace-rabbitmq/ace-lookup.py",
    "chars": 5766,
    "preview": "#!/usr/bin/env python\nimport json\nimport sys\nimport pika\nimport requests\nfrom argparse import ArgumentParser\nfrom json i"
  },
  {
    "path": "ACE-Docker/ace-sql/Dockerfile",
    "chars": 406,
    "preview": "FROM microsoft/mssql-server-linux\nMAINTAINER Jared Atkinson <jared@invoke-ir.com>\n\nENV ACCEPT_EULA Y\n\n# Create app direc"
  },
  {
    "path": "ACE-Docker/ace-sql/README.md",
    "chars": 1438,
    "preview": "Built on [microsoft/mssql-server-linux](https://hub.docker.com/r/microsoft/mssql-server-linux/), this images provides th"
  },
  {
    "path": "ACE-Docker/ace-sql/ace.sql",
    "chars": 3774,
    "preview": "CREATE TABLE [dbo].[Credentials] (\n    [Id]       UNIQUEIDENTIFIER NOT NULL,\n    [Password] NVARCHAR (MAX)   NOT NULL,\n "
  },
  {
    "path": "ACE-Docker/ace-sql/import-data.sh",
    "chars": 1257,
    "preview": "/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 e"
  },
  {
    "path": "ACE-Docker/ace.env",
    "chars": 147,
    "preview": "SA_PASSWORD=P@ssw0rd!\nMSSQL_PID=Standard\nRABBITMQ_DEFAULT_USER=ace\nRABBITMQ_DEFAULT_PASS=P@ssw0rd!\nAPIKEY=YOURAPIKEYHERE"
  },
  {
    "path": "ACE-Docker/docker-compose.yml",
    "chars": 924,
    "preview": "version: '2.1'\nnetworks:\n  ace:\n    driver: bridge\n    ipam:\n      config:\n        - subnet: 172.18.0.0/16\nservices:\n  a"
  },
  {
    "path": "ACE-Docker/settings.sh",
    "chars": 1930,
    "preview": "clear\n\nget_host_ip(){\n    # *********** Getting Host IP ***************\n    # https://github.com/Invoke-IR/ACE/blob/mast"
  },
  {
    "path": "ACE-Docker/start.sh",
    "chars": 8069,
    "preview": "# Get directory of script and change to it\nDIR=\"$( cd \"$( dirname \"${BASH_SOURCE[0]}\" )\" && pwd )\"\ncd $DIR\n\n# **********"
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/Download-AceFile.ps1",
    "chars": 831,
    "preview": "function Download-AceFile\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory)]\n        [string]\n     "
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/Get-AceComputer.ps1",
    "chars": 703,
    "preview": "function Get-AceComputer\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory)]\n        [string]\n       "
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/Get-AceCredential.ps1",
    "chars": 1139,
    "preview": "function Get-AceCredential\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory)]\n        [string]\n    "
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/Get-AceSchedule.ps1",
    "chars": 524,
    "preview": "function Get-AceSchedule\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory)]\n        [string]\n       "
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/Get-AceScript.ps1",
    "chars": 520,
    "preview": "function Get-AceScript\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory)]\n        [string]\n        $"
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/Get-AceSweep.ps1",
    "chars": 703,
    "preview": "function Get-AceSweep\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory)]\n        [string]\n        $U"
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/Get-AceSweepResult.ps1",
    "chars": 573,
    "preview": "function Get-AceSweepResult\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory)]\n        [string]\n    "
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/Get-AceUser.ps1",
    "chars": 516,
    "preview": "function Get-AceUser\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory)]\n        [string]\n        $Ur"
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/Invoke-AceWebRequest.ps1",
    "chars": 2607,
    "preview": "function Invoke-AceWebRequest\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n "
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/New-AceCredential.ps1",
    "chars": 855,
    "preview": "function New-AceCredential\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory)]\n        [string]\n     "
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/New-AceScheduledScan.ps1",
    "chars": 1147,
    "preview": "function New-AceScheduledScan\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory)]\n        [string[]]\n"
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/New-AceScript.ps1",
    "chars": 992,
    "preview": "function New-AceScript\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory)]\n        [string]\n        $"
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/New-AceUser.ps1",
    "chars": 976,
    "preview": "function New-AceUser\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory)]\n        [string]\n        $Ur"
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/Remove-AceCredential.ps1",
    "chars": 574,
    "preview": "function Remove-AceCredential\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory)]\n        [string]\n  "
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/Remove-AceScript.ps1",
    "chars": 566,
    "preview": "function Remove-AceScript\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory)]\n        [string]\n      "
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/Remove-AceUser.ps1",
    "chars": 562,
    "preview": "function Remove-AceUser\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory)]\n        [string]\n        "
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/Send-AceResult.ps1",
    "chars": 857,
    "preview": "function Send-AceResult\n{\n    <#\n    .SYNOPSIS\n    Short description\n    \n    .DESCRIPTION\n    Long description\n    \n   "
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/Start-AceDiscovery.ps1",
    "chars": 1412,
    "preview": "function Start-AceDiscovery\n{\n    [CmdletBinding(DefaultParameterSetName = \"Domain\")]\n    param\n    (\n        [Parameter"
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/Start-AceSweep.ps1",
    "chars": 1001,
    "preview": "function Start-AceSweep\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory)]\n        [string]\n        "
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/Update-AceCredential.ps1",
    "chars": 878,
    "preview": "function Update-AceCredential\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory)]\n        [string]\n  "
  },
  {
    "path": "ACE-Management/PS-ACE/Cmdlets/Update-AceUser.ps1",
    "chars": 990,
    "preview": "function Update-AceUser\n{\n    [CmdletBinding()]\n    param\n    (\n        [Parameter(Mandatory)]\n        [string]\n        "
  },
  {
    "path": "ACE-Management/PS-ACE/PS-ACE.psm1",
    "chars": 96,
    "preview": "Get-ChildItem \"$($PSScriptRoot)\\Cmdlets\\*\" -Include '*.ps1' |\n    ForEach-Object {. $_.FullName}"
  },
  {
    "path": "ACE-Management/PS-ACE/README.md",
    "chars": 2532,
    "preview": "# PS-ACE\nThe ACE Web Application provides a RESTful API for managment and sweep tasking. PS-ACE is a PowerShell module t"
  },
  {
    "path": "ACE-Management/PS-ACE/Scripts/ACE-Master.ps1",
    "chars": 273344,
    "preview": "function Start-AceScript\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n     "
  },
  {
    "path": "ACE-Management/PS-ACE/Scripts/ACE_Get-AccessToken.ps1",
    "chars": 99263,
    "preview": "function Start-AceScript\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n     "
  },
  {
    "path": "ACE-Management/PS-ACE/Scripts/ACE_Get-ArpCache.ps1",
    "chars": 31054,
    "preview": "function Start-AceScript\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n     "
  },
  {
    "path": "ACE-Management/PS-ACE/Scripts/ACE_Get-Atom.ps1",
    "chars": 27530,
    "preview": "function Start-AceScript\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n     "
  },
  {
    "path": "ACE-Management/PS-ACE/Scripts/ACE_Get-InjectedThread.ps1",
    "chars": 78846,
    "preview": "function Start-AceScript\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n      "
  },
  {
    "path": "ACE-Management/PS-ACE/Scripts/ACE_Get-KerberosTicketCache.ps1",
    "chars": 75946,
    "preview": "function Start-AceScript\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n     "
  },
  {
    "path": "ACE-Management/PS-ACE/Scripts/ACE_Get-LogonSession.ps1",
    "chars": 41486,
    "preview": "function Start-AceScript\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n     "
  },
  {
    "path": "ACE-Management/PS-ACE/Scripts/ACE_Get-MasterBootRecord.ps1",
    "chars": 11819,
    "preview": "function Start-AceScript\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n     "
  },
  {
    "path": "ACE-Management/PS-ACE/Scripts/ACE_Get-NetworkConnection.ps1",
    "chars": 42390,
    "preview": "function Start-AceScript\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n     "
  },
  {
    "path": "ACE-Management/PS-ACE/Scripts/ACE_Get-PSAutorun.ps1",
    "chars": 117403,
    "preview": "Function Get-PSAutorun {\n<#\n    .SYNOPSIS\n        Get Autorun entries.\n     \n    .DESCRIPTION\n        Retrieve a list o"
  },
  {
    "path": "ACE-Management/PS-ACE/Scripts/ACE_Get-PSIProcess.ps1",
    "chars": 13655,
    "preview": "function Start-AceScript\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n     "
  },
  {
    "path": "ACE-Management/PS-ACE/Scripts/ACE_Get-PSIScheduledTask.ps1",
    "chars": 12834,
    "preview": "function Start-AceScript\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n     "
  },
  {
    "path": "ACE-Management/PS-ACE/Scripts/ACE_Get-PSIService.ps1",
    "chars": 11435,
    "preview": "function Start-AceScript\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n     "
  },
  {
    "path": "ACE-Management/PS-ACE/Scripts/ACE_Get-PSIWindowsSecurityEvent.ps1",
    "chars": 26856,
    "preview": "function Start-AceScript\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n     "
  },
  {
    "path": "ACE-Management/PS-ACE/Scripts/ACE_Get-ScheduledJob.ps1",
    "chars": 3980,
    "preview": "function Start-AceScript\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n     "
  },
  {
    "path": "ACE-Management/PS-ACE/Scripts/ACE_Get-SecurityPackage.ps1",
    "chars": 39236,
    "preview": "function Start-AceScript\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n     "
  },
  {
    "path": "ACE-Management/PS-ACE/Scripts/ACE_Get-SimpleNamedPipe.ps1",
    "chars": 6291,
    "preview": "function Start-AceScript\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n     "
  },
  {
    "path": "ACE-Management/PS-ACE/Scripts/Invoke-MonsterWinRM.ps1",
    "chars": 5591,
    "preview": "# WinRM In Memory Deployment\nfunction Invoke-MonsterWinRM\n{\n    param\n    (\n        [Parameter()]\n        [string[]]\n  "
  },
  {
    "path": "ACE-Management/PS-ACE/Working/ACE_Get-PSIPrefetch.ps1",
    "chars": 7095,
    "preview": "function Start-AceScript\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n     "
  },
  {
    "path": "ACE-WebService/.gitignore",
    "chars": 3096,
    "preview": "# Download this file using PowerShell v3 under Windows with the following comand:\n# Invoke-WebRequest https://gist.gith"
  },
  {
    "path": "ACE-WebService/ACEWebService.sln",
    "chars": 1127,
    "preview": "\nMicrosoft Visual Studio Solution File, Format Version 12.00\n# Visual Studio 15\nVisualStudioVersion = 15.0.26430.16\nMin"
  },
  {
    "path": "ACE-WebService/Configure-AceWebService.ps1",
    "chars": 3321,
    "preview": "function Configure-AceWebService\n{\n    param\n    (\n        [Parameter()]\n        [string]\n        $FilePath = 'C:\\Windo"
  },
  {
    "path": "ACE-WebService/NuGet.config",
    "chars": 486,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n  <packageSources>\n    <add key=\"nuget.org\" value=\"https://api.nu"
  },
  {
    "path": "ACE-WebService/dockerfile",
    "chars": 290,
    "preview": "FROM microsoft/aspnetcore-build AS builder\nWORKDIR /source\nCOPY *.csproj .\nCOPY nuget.config .\nRUN dotnet restore\nCOPY ."
  },
  {
    "path": "ACE-WebService/src/ACEWebService/ACEWebService.csproj",
    "chars": 2906,
    "preview": "<Project Sdk=\"Microsoft.NET.Sdk.Web\">\n\n  <PropertyGroup>\n    <TargetFramework>netcoreapp2.0</TargetFramework>\n    <Pres"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/App.config",
    "chars": 94,
    "preview": "<configuration>\n   <runtime>\n      <gcServer enabled=\"true\"/>\n   </runtime>\n</configuration>\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/AppSettings.cs",
    "chars": 372,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.Linq;\nusing System.Threading.Tasks;\n\nnamespace ACEWebServi"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Controllers/ComputerController.cs",
    "chars": 904,
    "preview": "using ACEWebService.Entities;\nusing Microsoft.AspNetCore.Authorization;\nusing Microsoft.AspNetCore.Mvc;\nusing System;\nu"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Controllers/CredentialController.cs",
    "chars": 4583,
    "preview": "using ACEWebService.Entities;\nusing ACEWebService.Security;\nusing ACEWebService.Services;\nusing ACEWebService.ViewModel"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Controllers/DiscoverController.cs",
    "chars": 1434,
    "preview": "using ACEWebService.Services;\nusing ACEWebService.ViewModels;\nusing Microsoft.AspNetCore.Authorization;\nusing Microsoft"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Controllers/DownloadController.cs",
    "chars": 2018,
    "preview": "using ACEWebService.Entities;\nusing ACEWebService.Services;\nusing ACEWebService.ViewModels;\nusing Microsoft.AspNetCore."
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Controllers/ResultController.cs",
    "chars": 979,
    "preview": "using ACEWebService.Services;\nusing ACEWebService.ViewModels;\nusing Microsoft.AspNetCore.Mvc;\nusing Microsoft.Extension"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Controllers/ScanController.cs",
    "chars": 2609,
    "preview": "using ACEWebService.Entities;\nusing Microsoft.AspNetCore.Authorization;\nusing Microsoft.AspNetCore.Mvc;\nusing System;\nu"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Controllers/ScriptController.cs",
    "chars": 3822,
    "preview": "using ACEWebService.Entities;\nusing ACEWebService.ViewModels;\nusing Microsoft.AspNetCore.Authorization;\nusing Microsoft"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Controllers/SweepController.cs",
    "chars": 2371,
    "preview": "using ACEWebService.Entities;\nusing ACEWebService.Services;\nusing ACEWebService.ViewModels;\nusing Microsoft.AspNetCore."
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Controllers/UserController.cs",
    "chars": 3804,
    "preview": "using ACEWebService.Entities;\nusing ACEWebService.ViewModels;\nusing Microsoft.AspNetCore.Authorization;\nusing Microsoft"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/DbModelBuilder.cs",
    "chars": 203,
    "preview": "using System;\n\nnamespace ACEWebService.Entities\n{\n    internal class DbModelBuilder\n    {\n        internal object Entit"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Entities/ACEWebServiceDbContext.cs",
    "chars": 696,
    "preview": "\nusing Microsoft.EntityFrameworkCore;\n\nnamespace ACEWebService.Entities\n{\n    public class ACEWebServiceDbContext : DbC"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Entities/Computer.cs",
    "chars": 645,
    "preview": "using System;\nusing System.ComponentModel.DataAnnotations;\nusing System.ComponentModel.DataAnnotations.Schema;\n\nnamespa"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Entities/ComputerGroup.cs",
    "chars": 496,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.ComponentModel.DataAnnotations;\nusing System.ComponentMode"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Entities/Credential.cs",
    "chars": 431,
    "preview": "using System;\nusing System.ComponentModel.DataAnnotations;\nusing System.ComponentModel.DataAnnotations.Schema;\n\nnamespa"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Entities/Download.cs",
    "chars": 625,
    "preview": "using System;\nusing System.ComponentModel.DataAnnotations;\nusing System.ComponentModel.DataAnnotations.Schema;\n\nnamespa"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Entities/Scan.cs",
    "chars": 584,
    "preview": "using System;\nusing System.ComponentModel.DataAnnotations;\nusing System.ComponentModel.DataAnnotations.Schema;\n\nnamespa"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Entities/Schedule.cs",
    "chars": 579,
    "preview": "using System;\nusing System.ComponentModel.DataAnnotations;\nusing System.ComponentModel.DataAnnotations.Schema;\n\nnamespa"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Entities/Script.cs",
    "chars": 689,
    "preview": "using System;\nusing System.ComponentModel.DataAnnotations;\nusing System.ComponentModel.DataAnnotations.Schema;\n\nnamespa"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Entities/Sweep.cs",
    "chars": 603,
    "preview": "using System;\nusing System.Collections.Generic;\nusing System.ComponentModel.DataAnnotations;\nusing System.ComponentMode"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Entities/User.cs",
    "chars": 555,
    "preview": "using System;\nusing System.ComponentModel.DataAnnotations;\nusing System.ComponentModel.DataAnnotations.Schema;\n\nnamespa"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170322221439_MyFirstMigration.Designer.cs",
    "chars": 4823,
    "preview": "using System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft."
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170322221439_MyFirstMigration.cs",
    "chars": 5857,
    "preview": "using System;\nusing System.Collections.Generic;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace ACEWebServic"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170322222622_MySecondMigration.Designer.cs",
    "chars": 5076,
    "preview": "using System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft."
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170322222622_MySecondMigration.cs",
    "chars": 1332,
    "preview": "using System;\nusing System.Collections.Generic;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace ACEWebServic"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170417201050_MyThirdMigration.Designer.cs",
    "chars": 5074,
    "preview": "using System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft."
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170417201050_MyThirdMigration.cs",
    "chars": 388,
    "preview": "using System;\nusing System.Collections.Generic;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace ACEWebServic"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170420231736_MyFourthMigration.Designer.cs",
    "chars": 5128,
    "preview": "using System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft."
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170420231736_MyFourthMigration.cs",
    "chars": 679,
    "preview": "using System;\nusing System.Collections.Generic;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace ACEWebServic"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170421030619_MyFifthMigration.Designer.cs",
    "chars": 5184,
    "preview": "using System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft."
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170421030619_MyFifthMigration.cs",
    "chars": 734,
    "preview": "using System;\nusing System.Collections.Generic;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace ACEWebServic"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170429215921_MySixthMigration.Designer.cs",
    "chars": 5559,
    "preview": "using System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft."
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170429215921_MySixthMigration.cs",
    "chars": 2411,
    "preview": "using System;\nusing System.Collections.Generic;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace ACEWebServic"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170430141205_MySeventhMigration.Designer.cs",
    "chars": 6352,
    "preview": "using System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft."
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170430141205_MySeventhMigration.cs",
    "chars": 1328,
    "preview": "using System;\nusing System.Collections.Generic;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace ACEWebServic"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170707032113_MyEigthMigration.Designer.cs",
    "chars": 6456,
    "preview": "using System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft."
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170707032113_MyEigthMigration.cs",
    "chars": 918,
    "preview": "using System;\nusing System.Collections.Generic;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace ACEWebServic"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170707040959_MyNinthMigration.Designer.cs",
    "chars": 6410,
    "preview": "using System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft."
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170707040959_MyNinthMigration.cs",
    "chars": 1202,
    "preview": "using System;\nusing System.Collections.Generic;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace ACEWebServic"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170707042221_MyTenthMigration.Designer.cs",
    "chars": 6463,
    "preview": "using System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft."
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170707042221_MyTenthMigration.cs",
    "chars": 686,
    "preview": "using System;\nusing System.Collections.Generic;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace ACEWebServic"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170713053904_MyEleventhMigration.Designer.cs",
    "chars": 6651,
    "preview": "using System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft."
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20170713053904_MyEleventhMigration.cs",
    "chars": 979,
    "preview": "using System;\nusing System.Collections.Generic;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace ACEWebServic"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20171116210534_MyTwelfthMigration.Designer.cs",
    "chars": 6259,
    "preview": "using System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft."
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20171116210534_MyTwelfthMigration.cs",
    "chars": 1756,
    "preview": "using System;\nusing System.Collections.Generic;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace ACEWebServic"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20171116211023_MyThirteenthMigration.Designer.cs",
    "chars": 6034,
    "preview": "using System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft."
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20171116211023_MyThirteenthMigration.cs",
    "chars": 2452,
    "preview": "using System;\nusing System.Collections.Generic;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace ACEWebServic"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20171116233431_MyFourteenthMigration.Designer.cs",
    "chars": 6093,
    "preview": "using System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft."
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/20171116233431_MyFourteenthMigration.cs",
    "chars": 756,
    "preview": "using System;\nusing System.Collections.Generic;\nusing Microsoft.EntityFrameworkCore.Migrations;\n\nnamespace ACEWebServic"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Migrations/ACEWebServiceDbContextModelSnapshot.cs",
    "chars": 6061,
    "preview": "using System;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.EntityFrameworkCore.Infrastructure;\nusing Microsoft."
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Program.cs",
    "chars": 488,
    "preview": "using System.IO;\nusing Microsoft.AspNetCore.Hosting;\nusing Microsoft.AspNetCore.Builder;\n\nnamespace ACEWebService\n{\n   "
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Project_Readme.html",
    "chars": 6657,
    "preview": "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n    <meta charset=\"utf-8\" />\n    <title>Welcome to ASP.NET Core</title>\n    <st"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Properties/PublishProfiles/ACEWebService-publish.ps1",
    "chars": 772,
    "preview": "[cmdletbinding(SupportsShouldProcess=$true)]\nparam($publishProperties=@{}, $packOutput, $pubProfilePath)\n\n# to learn mo"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Properties/PublishProfiles/ACEWebService.pubxml",
    "chars": 1261,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\nThis file is used by the publish/package process of your Web project. You c"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Properties/PublishProfiles/FileSystem-publish.ps1",
    "chars": 772,
    "preview": "[cmdletbinding(SupportsShouldProcess=$true)]\nparam($publishProperties=@{}, $packOutput, $pubProfilePath)\n\n# to learn mo"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Properties/PublishProfiles/FileSystem.pubxml",
    "chars": 911,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\nThis file is used by the publish/package process of your Web project. You c"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Properties/PublishProfiles/publish-module.psm1",
    "chars": 48625,
    "preview": "# WARNING:  DO NOT MODIFY this file. Visual Studio will override it.\nparam()\n\n$script:AspNetPublishHandlers = @{}\n\n<#\nT"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Properties/launchSettings.json",
    "chars": 624,
    "preview": "{\n  \"iisSettings\": {\n    \"windowsAuthentication\": false,\n    \"anonymousAuthentication\": true,\n    \"iisExpress\": {\n      "
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Security/ApiKeyPolicy.cs",
    "chars": 1401,
    "preview": "using ACEWebService.Entities;\nusing ACEWebService.Security;\nusing Microsoft.AspNetCore.Authorization;\nusing Microsoft.E"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Security/IsAdminPolicy.cs",
    "chars": 1461,
    "preview": "using ACEWebService.Entities;\nusing Microsoft.AspNetCore.Authorization;\nusing Microsoft.Extensions.Primitives;\nusing Sy"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Services/IAceConfiguration.cs",
    "chars": 381,
    "preview": "using Microsoft.Extensions.Configuration;\n\nnamespace ACEWebService.Services\n{\n    public interface IAceConfiguration\n  "
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Services/ICryptographyService.cs",
    "chars": 760,
    "preview": "using Microsoft.AspNetCore.DataProtection;\n\nnamespace ACEWebService.Services\n{\n    public interface ICryptographyServic"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Services/IDiscoveryService.cs",
    "chars": 11438,
    "preview": "using ACEWebService.Entities;\nusing ACEWebService.ViewModels;\nusing System;\nusing System.Collections.Generic;\n//using S"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Services/IDownloadService.cs",
    "chars": 4786,
    "preview": "using ACEWebService.Entities;\nusing ACEWebService.ViewModels;\nusing Microsoft.Extensions.Options;\nusing Microsoft.Manag"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Services/ISweepExecutionService.cs",
    "chars": 10403,
    "preview": "using ACEWebService.Entities;\nusing ACEWebService.ViewModels;\nusing Microsoft.EntityFrameworkCore;\nusing Microsoft.Mana"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Services/ISweepResultProcessorService.cs",
    "chars": 1718,
    "preview": "using ACEWebService.ViewModels;\nusing Microsoft.Extensions.Options;\nusing RabbitMQ.Client;\nusing System;\nusing System.I"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/Startup.cs",
    "chars": 6029,
    "preview": "using ACEWebService.Services;\nusing ACEWebService.Entities;\nusing ACEWebService.Security;\nusing Microsoft.AspNetCore.Bu"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/ViewModels/ArbitrarySweepViewModel.cs",
    "chars": 433,
    "preview": "using System;\nusing System.Collections;\nusing System.ComponentModel.DataAnnotations;\n\nnamespace ACEWebService.ViewModel"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/ViewModels/CredentialViewModel.cs",
    "chars": 263,
    "preview": "using System.ComponentModel.DataAnnotations;\n\nnamespace ACEWebService.ViewModels\n{\n    public class CredentialViewModel"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/ViewModels/DiscoveryActiveDirectoryViewModel.cs",
    "chars": 290,
    "preview": "using System;\nusing System.ComponentModel.DataAnnotations;\n\nnamespace ACEWebService.ViewModels\n{\n    public class Disco"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/ViewModels/DiscoveryComputerListViewModel.cs",
    "chars": 296,
    "preview": "using System;\nusing System.ComponentModel.DataAnnotations;\n\nnamespace ACEWebService.ViewModels\n{\n    public class Disco"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/ViewModels/DownloadReceiveViewModel.cs",
    "chars": 408,
    "preview": "using System;\nusing System.ComponentModel.DataAnnotations;\n\nnamespace ACEWebService.ViewModels\n{\n    public class Downl"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/ViewModels/DownloadRequestViewModel.cs",
    "chars": 340,
    "preview": "using System;\nusing System.ComponentModel.DataAnnotations;\n\nnamespace ACEWebService.ViewModels\n{\n    public class Downl"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/ViewModels/ErrorViewModel.cs",
    "chars": 310,
    "preview": "using Newtonsoft.Json;\n\nnamespace VTIProxy.ViewModels\n{\n    public class ErrorViewModel\n    {\n        public string Mes"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/ViewModels/FileViewModel.cs",
    "chars": 382,
    "preview": "using System.ComponentModel.DataAnnotations;\n\nnamespace ACEWebService.ViewModels\n{\n    public class FileViewModel\n    {"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/ViewModels/ScheduleIntervalViewModel.cs",
    "chars": 554,
    "preview": "using System.ComponentModel.DataAnnotations;\n\nnamespace ACEWebService.ViewModels\n{\n    public class ScheduleIntervalVie"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/ViewModels/ScheduleTimeViewModel.cs",
    "chars": 612,
    "preview": "using ACEWebService.Entities;\nusing System;\nusing System.ComponentModel.DataAnnotations;\n\nnamespace ACEWebService.ViewM"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/ViewModels/SweepExecutionViewModel.cs",
    "chars": 409,
    "preview": "using System;\nusing System.ComponentModel.DataAnnotations;\n\nnamespace ACEWebService.ViewModels\n{\n    public class Sweep"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/ViewModels/SweepResultViewModel.cs",
    "chars": 369,
    "preview": "using Newtonsoft.Json.Linq;\nusing System;\nusing System.ComponentModel.DataAnnotations;\n\nnamespace ACEWebService.ViewMod"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/ViewModels/UserViewModel.cs",
    "chars": 326,
    "preview": "using System.ComponentModel.DataAnnotations;\n\nnamespace ACEWebService.ViewModels\n{\n    public class UserViewModel\n    {"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/appsettings.Production.json",
    "chars": 589,
    "preview": "{\n  \"Logging\": {\n    \"IncludeScopes\": false,\n    \"LogLevel\": {\n      \"Default\": \"Debug\",\n      \"System\": \"Information\","
  },
  {
    "path": "ACE-WebService/src/ACEWebService/appsettings.json",
    "chars": 529,
    "preview": "{\n  \"Logging\": {\n    \"IncludeScopes\": false,\n    \"LogLevel\": {\n      \"Default\": \"Debug\",\n      \"System\": \"Information\","
  },
  {
    "path": "ACE-WebService/src/ACEWebService/nuget.config",
    "chars": 486,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n  <packageSources>\n    <add key=\"nuget.org\" value=\"https://api.nu"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/scripts/Download-AceFile.ps1",
    "chars": 3474,
    "preview": "function Download-AceFile\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $Uri,\n\n     "
  },
  {
    "path": "ACE-WebService/src/ACEWebService/scripts/Start-AceScript.ps1",
    "chars": 5483,
    "preview": "function Start-AceScript\n{\n    param\n    (\n        [Parameter(Mandatory = $true)]\n        [string]\n        $ServerUri,\n\n"
  },
  {
    "path": "ACE-WebService/src/ACEWebService/web.config",
    "chars": 587,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<configuration>\n\n  <!--\n    Configure your application settings in appsettings.j"
  },
  {
    "path": "LICENSE-Quartz.NET",
    "chars": 11357,
    "preview": "\n                                 Apache License\n                           Version 2.0, January 2004\n                  "
  },
  {
    "path": "LICENSE-RabbitMQ",
    "chars": 451,
    "preview": "This package, the RabbitMQ .NET client library, is dual-licensed under\nthe Apache License v2 and the Mozilla Public Lice"
  },
  {
    "path": "LICENSE-SSH.NET",
    "chars": 1046,
    "preview": "\nThe MIT License (MIT)\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software an"
  },
  {
    "path": "LICENSE-osxcollector",
    "chars": 607,
    "preview": "This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public Licens"
  },
  {
    "path": "README.md",
    "chars": 2839,
    "preview": "# Automated Collection and Enrichment\nThe Automated Collection and Enrichment (ACE) platform is a suite of tools for thr"
  }
]

About this extraction

This page contains the full source code of the Invoke-IR/ACE GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 159 files (1.2 MB), approximately 294.7k tokens, and a symbol index with 216 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!