# Scripting

## Scripts vs. Modules

<table><thead><tr><th width="345">Script</th><th>Module</th></tr></thead><tbody><tr><td>An executable text file</td><td>Can be a simple script or a collection of them</td></tr><tr><td>Contains cmdlets &#x26; functions</td><td>Contains scripts, cmdlets, &#x26; functions</td></tr><tr><td>Execute directly (<code>.\script.ps1</code>)</td><td>Is imported (<code>Import-Module .\module.ps1</code>)</td></tr></tbody></table>

## File Extensions

<table><thead><tr><th width="132" align="right">Extension</th><th>Description</th></tr></thead><tbody><tr><td align="right"><code>ps1</code></td><td>The <code>*.ps1</code> file extension represents executable PowerShell scripts.</td></tr><tr><td align="right"><code>psm1</code></td><td>The <code>*.psm1</code> file extension represents a PowerShell module file. It defines what the module is and what is contained within it.</td></tr><tr><td align="right"><code>psd1</code></td><td>The <code>*.psd1</code> is a PowerShell data file detailing the contents of a PowerShell module in a table of key/value pairs (<strong>manifest</strong>).</td></tr></tbody></table>

## Creating a Module

### Components

A module is made up of `4`essential components:

1. A directory containing all the required files and content, saved somewhere within `$env:PSModulePath`.
2. A `manifest` file listing all files and pertinent information about the module and its function. This could include associated scripts, dependencies, the author, example usage, etc.
3. Some code file - usually either a PowerShell script (`.ps1`) or a (`.psm1`) module file that contains our script functions and other information.
4. Other resources the module needs, such as help files, scripts, and other supporting documents.

### Manifest

A module manifest is a simple `.psd1` file that contains a hash table. The keys and values in the hash table perform the following functions:

* Describe the contents and attributes of the module.
* Define the prerequisites.
* Determine how the components are processed.

If you add a manifest file to the module folder, you can reference multiple files as a single unit by referencing the manifest. The manifest describes the following information:

* Metadata about the module.
* Prerequisites needed to import the module, such as the Windows PowerShell version, the common language runtime (CLR) version, and the required modules.
* Processing directives, such as the scripts, formats, and types to process.
* Restrictions on the module members to export, such as the aliases, functions, variables, and cmdlets to export.

&#x20;All the lines in the manifest files are optional except for the `ModuleVersion` line.

```powershell
# Creating a manifest file (Pass-Thru prints the file's content to stdout)
New-ModuleManifest -Path <path\file-name>.psd1 -PassThru
```

### Script

```powershell
# Creating a script file
New-Item quick-recon.psm1 -ItemType File
```

### Protecting Functions

If we don't want our functions to be accessed, exported or utilized by other scripts or processes within PS.

```powershell
# If it is left blank within the file, nothing can be exported
Export-ModuleMember
# Specific objects can be defined to be exported
Export-ModuleMember -Function Get-Recon -Variable Hostname
# Export all functions, but only the Hostname variable
Export-ModuleMember -Function * -Variable Hostname
```

### Module

{% code title="quick-recon.psm1" overflow="wrap" %}

```powershell
import-module ActiveDirectory

<# 
.Description  
This function performs some simple recon tasks for the user. We import the module and then issue the 'Get-Recon' command to retrieve our output. Each variable and line within the function and script are commented for your understanding. Right now, this only works on the local host from which you run it, and the output will be sent to a file named 'recon.txt' on the Desktop of the user who opened the shell. Remote Recon functions coming soon!  

.Example  
After importing the module run "Get-Recon"
'Get-Recon


    Directory: C:\Users\MTanaka\Desktop


Mode                 LastWriteTime         Length Name                                                                                                                                        
----                 -------------         ------ ----                                                                                                                                        
-a----         11/3/2022  12:46 PM              0 recon.txt '

.Notes  
Remote Recon functions coming soon! This script serves as our initial introduction to writing functions and scripts and making PowerShell modules.  

#>
function Get-Recon {  
    # Collect the hostname of our PC
    $Hostname = $env:ComputerName  
    # Collect the IP configuration
    $IP = ipconfig
    # Collect basic domain information
    $Domain = Get-ADDomain 
    # Output the users who have logged in and built out a basic directory structure in "C:\Users"
    $Users = Get-ChildItem C:\Users\
    # Create a new file to place our recon results in
    new-Item ~\Desktop\recon.txt -ItemType File 
    # A variable to hold the results of our other variables 
    $Vars = "***---Hostname info---***", $Hostname, "***---Domain Info---***", $Domain, "***---IP INFO---***",  $IP, "***---USERS---***", $Users
    # It does the thing 
    Add-Content ~\Desktop\recon.txt $Vars
  } 

Export-ModuleMember -Function Get-Recon -Variable Hostname 
```

{% endcode %}

{% code overflow="wrap" %}

```powershell
# Import the quick-recon module
PS C:\htb> Import-Module 'C:\Users\MTanaka\Documents\WindowsPowerShell\Modules\quick-recon.psm1`
# Check active modules
PS C:\Users\MTanaka\Documents\WindowsPowerShell\Modules\quick-recon> get-module

ModuleType Version    Name                                ExportedCommands
---------- -------    ----                                ----------------
Manifest   3.1.0.0    Microsoft.PowerShell.Management     {Add-Computer, Add-Content, Checkpoint-Computer, Clear-Con...
Script     2.0.0      PSReadline                          {Get-PSReadLineKeyHandler, Get-PSReadLineOption, Remove-PS...
Script     0.0        quick-recon                         Get-Recon
```

{% endcode %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://x7331.gitbook.io/notes/windows-shells/powershell/scripting.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
