Task 574: .PS1 File Format

Task 574: .PS1 File Format

File Format Specifications for .PS1

The .PS1 file format is used for Windows PowerShell scripts (and cross-platform with PowerShell Core). It is not a binary format with a structured header or fixed properties like many proprietary file types; instead, it is a plain text file containing PowerShell commands and code, typically encoded in UTF-8 (with or without BOM) or UTF-16. The specifications are defined by Microsoft's PowerShell language and scripting guidelines, which outline syntax, command structure, and execution behavior rather than a low-level byte format. Key references include the official PowerShell documentation, which states that a .ps1 file is simply a text file with one or more PowerShell commands. The language specification covers scripting rules but does not define a binary "format" since these are executable text scripts.

List of all the properties of this file format intrinsic to its file system
Since .PS1 is a plain text format without inherent binary structures, there are no format-specific "properties" like headers or magic numbers. However, interpreting "properties intrinsic to its file system" as standard file system metadata attributes (common to files in operating systems like Windows NTFS, where .PS1 originated, or Linux/macOS), the following are relevant and can be retrieved for any .PS1 file:

  • File Name
  • File Size (in bytes)
  • Creation Time
  • Last Modification Time
  • Last Access Time
  • Read-Only Attribute (boolean)
  • Hidden Attribute (boolean)
  • System Attribute (boolean)
  • Owner (user ID or name)
  • Permissions (read/write/execute modes, varying by OS)

These are not unique to .PS1 but are file system-level properties applicable to it.

Two direct download links for files of format .PS1

Ghost blog embedded HTML JavaScript for drag-and-drop .PS1 file dump
(Assuming "ghost blog embedded" refers to embeddable HTML/JS code suitable for a blog post, e.g., on Ghost platform. This is a self-contained snippet using the browser's File API to handle drag-and-drop of a .PS1 file and display the available properties. Note: Browser security limits access to some file system properties like creation time or owner; only basic ones are available. Drop a .PS1 file onto the designated area to see the dump.)

PS1 File Properties Dumper

Drag and Drop .PS1 File

Drop .PS1 file here

    

Python class for .PS1 file
(This class uses pathlib and os to handle any .PS1 file by path. It "opens" the file for validation but focuses on reading and printing file system properties. "Decode" is irrelevant for text, but "read" gets properties; "write" is implemented as a method to set basic attributes like read-only or modification time where possible. Run with PS1Handler('path/to/file.ps1').print_properties().)

import os
import pathlib
import stat
import time

class PS1Handler:
    def __init__(self, file_path):
        self.file_path = pathlib.Path(file_path)
        if not self.file_path.suffix.lower() == '.ps1':
            raise ValueError("File must have .ps1 extension")
        if not self.file_path.exists():
            raise FileNotFoundError("File does not exist")

    def read_properties(self):
        st = self.file_path.stat()
        return {
            'File Name': self.file_path.name,
            'File Size (bytes)': st.st_size,
            'Creation Time': time.ctime(st.st_ctime),
            'Last Modification Time': time.ctime(st.st_mtime),
            'Last Access Time': time.ctime(st.st_atime),
            'Read-Only Attribute': bool(st.st_mode & stat.S_IREAD) and not bool(st.st_mode & stat.S_IWRITE),
            'Hidden Attribute': bool(self.file_path.name.startswith('.')) if os.name != 'nt' else bool(os.stat(self.file_path).st_file_attributes & 0x2),
            'System Attribute': bool(os.stat(self.file_path).st_file_attributes & 0x4) if os.name == 'nt' else False,
            'Owner': os.getlogin() if os.name == 'nt' else st.st_uid,
            'Permissions': oct(st.st_mode)[-3:]
        }

    def write_attribute(self, attribute, value):
        if attribute == 'read_only':
            mode = os.stat(self.file_path).st_mode
            new_mode = mode & ~stat.S_IWRITE if value else mode | stat.S_IWRITE
            os.chmod(self.file_path, new_mode)
        elif attribute == 'modification_time':
            os.utime(self.file_path, (os.stat(self.file_path).st_atime, value))
        # Other writes (e.g., owner) require elevated privileges and are OS-specific

    def print_properties(self):
        props = self.read_properties()
        for key, val in props.items():
            print(f"{key}: {val}")

# Example usage:
# handler = PS1Handler('example.ps1')
# handler.print_properties()
# handler.write_attribute('read_only', True)

Java class for .PS1 file
(This class uses java.nio.file to handle the file. It validates .PS1 extension, reads properties, and supports basic writes like setting read-only or last modification time. Run with new PS1Handler(Paths.get("path/to/file.ps1")).printProperties();.)

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.BasicFileAttributeView;
import java.nio.file.attribute.FileOwnerAttributeView;
import java.nio.file.attribute.PosixFileAttributes;
import java.nio.file.attribute.PosixFilePermissions;
import java.util.Date;

public class PS1Handler {
    private final Path filePath;

    public PS1Handler(Path filePath) {
        this.filePath = filePath;
        if (!filePath.toString().toLowerCase().endsWith(".ps1")) {
            throw new IllegalArgumentException("File must have .ps1 extension");
        }
        if (!Files.exists(filePath)) {
            throw new IllegalArgumentException("File does not exist");
        }
    }

    public void readAndPrintProperties() throws IOException {
        BasicFileAttributes attrs = Files.readAttributes(filePath, BasicFileAttributes.class);
        FileOwnerAttributeView ownerView = Files.getFileAttributeView(filePath, FileOwnerAttributeView.class);
        System.out.println("File Name: " + filePath.getFileName());
        System.out.println("File Size (bytes): " + attrs.size());
        System.out.println("Creation Time: " + new Date(attrs.creationTime().toMillis()));
        System.out.println("Last Modification Time: " + new Date(attrs.lastModifiedTime().toMillis()));
        System.out.println("Last Access Time: " + new Date(attrs.lastAccessTime().toMillis()));
        System.out.println("Read-Only Attribute: " + !Files.isWritable(filePath));
        System.out.println("Hidden Attribute: " + Files.isHidden(filePath));
        System.out.println("System Attribute: false"); // Not directly supported in Java BasicFileAttributes
        System.out.println("Owner: " + ownerView.getOwner().getName());
        try {
            PosixFileAttributes posixAttrs = Files.readAttributes(filePath, PosixFileAttributes.class);
            System.out.println("Permissions: " + PosixFilePermissions.toString(posixAttrs.permissions()));
        } catch (UnsupportedOperationException e) {
            System.out.println("Permissions: Not supported on this OS");
        }
    }

    public void writeAttribute(String attribute, Object value) throws IOException {
        BasicFileAttributeView attrView = Files.getFileAttributeView(filePath, BasicFileAttributeView.class);
        if ("read_only".equals(attribute)) {
            Files.setAttribute(filePath, "dos:readonly", (Boolean) value);
        } else if ("modification_time".equals(attribute)) {
            attrView.setTimes(null, java.nio.file.attribute.FileTime.fromMillis((Long) value), null);
        }
        // Other writes may require additional views or privileges
    }

    public static void main(String[] args) throws IOException {
        // Example usage
        PS1Handler handler = new PS1Handler(Paths.get("example.ps1"));
        handler.readAndPrintProperties();
        // handler.writeAttribute("read_only", true);
    }
}

JavaScript class for .PS1 file
(This class uses Node.js fs module for server-side handling. It validates .PS1, reads properties, and supports basic writes. Run with new PS1Handler('path/to/file.ps1').printProperties(); in a Node.js environment.)

const fs = require('fs');
const path = require('path');

class PS1Handler {
    constructor(filePath) {
        this.filePath = filePath;
        if (!path.extname(filePath).toLowerCase() === '.ps1') {
            throw new Error('File must have .ps1 extension');
        }
        if (!fs.existsSync(filePath)) {
            throw new Error('File does not exist');
        }
    }

    readProperties() {
        const stats = fs.statSync(this.filePath);
        return {
            'File Name': path.basename(this.filePath),
            'File Size (bytes)': stats.size,
            'Creation Time': stats.birthtime.toString(),
            'Last Modification Time': stats.mtime.toString(),
            'Last Access Time': stats.atime.toString(),
            'Read-Only Attribute': (stats.mode & 0o200) === 0, // Approximate, checks writable bit
            'Hidden Attribute': path.basename(this.filePath).startsWith('.'),
            'System Attribute': false, // Not directly available in Node.js fs
            'Owner': stats.uid,
            'Permissions': (stats.mode & 0o777).toString(8)
        };
    }

    writeAttribute(attribute, value) {
        if (attribute === 'read_only') {
            let mode = fs.statSync(this.filePath).mode;
            mode = value ? mode & ~0o222 : mode | 0o222; // Remove/ add write bits
            fs.chmodSync(this.filePath, mode);
        } else if (attribute === 'modification_time') {
            fs.utimesSync(this.filePath, new Date(), new Date(value));
        }
    }

    printProperties() {
        const props = this.readProperties();
        for (const [key, val] of Object.entries(props)) {
            console.log(`${key}: ${val}`);
        }
    }
}

// Example usage:
// const handler = new PS1Handler('example.ps1');
// handler.printProperties();
// handler.writeAttribute('read_only', true);

C class for .PS1 file
(Interpreting "c class" as C++ class, since C lacks classes. This uses <filesystem> and <sys/stat.h> for properties. Compiles with C++17. It validates .PS1, reads properties, and supports basic writes. Run with PS1Handler handler("path/to/file.ps1"); handler.printProperties();.)

#include <iostream>
#include <filesystem>
#include <sys/stat.h>
#include <ctime>
#include <string>

class PS1Handler {
private:
    std::filesystem::path filePath;

public:
    PS1Handler(const std::string& path) : filePath(path) {
        if (filePath.extension().string() != ".ps1") {
            throw std::invalid_argument("File must have .ps1 extension");
        }
        if (!std::filesystem::exists(filePath)) {
            throw std::invalid_argument("File does not exist");
        }
    }

    void printProperties() {
        struct stat st;
        if (stat(filePath.string().c_str(), &st) == 0) {
            std::cout << "File Name: " << filePath.filename().string() << std::endl;
            std::cout << "File Size (bytes): " << st.st_size << std::endl;
            std::cout << "Creation Time: " << std::ctime(&st.st_ctime);
            std::cout << "Last Modification Time: " << std::ctime(&st.st_mtime);
            std::cout << "Last Access Time: " << std::ctime(&st.st_atime);
            std::cout << "Read-Only Attribute: " << ((st.st_mode & S_IWUSR) == 0) << std::endl;
            std::cout << "Hidden Attribute: " << (filePath.filename().string()[0] == '.') << std::endl;
            std::cout << "System Attribute: 0" << std::endl; // Not standard in POSIX
            std::cout << "Owner: " << st.st_uid << std::endl;
            std::cout << "Permissions: " << std::oct << (st.st_mode & 0777) << std::endl;
        }
    }

    void writeAttribute(const std::string& attribute, bool value) {
        if (attribute == "read_only") {
            struct stat st;
            stat(filePath.string().c_str(), &st);
            mode_t newMode = value ? (st.st_mode & ~0222) : (st.st_mode | 0222);
            chmod(filePath.string().c_str(), newMode);
        }
        // For modification time: use utimes() with struct timeval
    }
};

// Example usage:
// int main() {
//     try {
//         PS1Handler handler("example.ps1");
//         handler.printProperties();
//     } catch (const std::exception& e) {
//         std::cerr << e.what() << std::endl;
//     }
//     return 0;
// }