Task 577: .PSM1 File Format

Task 577: .PSM1 File Format

1. List of all the properties of this file format intrinsic to its file system

The .PSM1 file format is a text-based script module file used in PowerShell. It does not have a structured binary format with fixed fields or headers; instead, it contains free-form PowerShell code in text form (typically UTF-8 encoded). Therefore, there are no format-specific intrinsic properties beyond standard file system metadata. The properties intrinsic to its representation in the file system (e.g., on NTFS or similar) include:

  • File Name: The name of the file, including the .PSM1 extension.
  • File Path: The full directory path where the file is located.
  • Size: The size of the file in bytes.
  • Creation Time: The date and time when the file was created.
  • Last Modified Time: The date and time when the file was last modified.
  • Last Access Time: The date and time when the file was last accessed.
  • Attributes: File attributes such as ReadOnly, Hidden, System, Archive, etc.

These are standard for any file and can be accessed via file system APIs.

3. Ghost blog embedded html javascript that allows a user to drag n drop a file of format .PSM1 and it will dump to screen all these properties

Here's a simple self-contained HTML page with embedded JavaScript that can be embedded in a Ghost blog post (or any HTML-enabled blog). It creates a drag-and-drop area. When a .PSM1 file is dropped, it displays the file system properties (limited to what the browser's File API provides: name, size, type, last modified). Note: Browser security restricts access to full path, creation/access times, and attributes; those require server-side or Node.js handling.

PSM1 File Properties Dumper

Drag and Drop .PSM1 File

Drop .PSM1 file here

4. Python class that can open any file of format .PSM1 and decode read and write and print to console all the properties from the above list

Here's a Python class using pathlib and os to handle the file. It opens/reads the file content (decoding as UTF-8 text), allows writing new content, and prints the file system properties.

import os
from pathlib import Path
import stat
import time

class PSM1Handler:
    def __init__(self, file_path):
        self.file_path = Path(file_path)
        if not self.file_path.suffix.lower() == '.psm1':
            raise ValueError("File must have .psm1 extension")
        self.content = None

    def read(self):
        """Read and decode the file content as UTF-8."""
        with open(self.file_path, 'r', encoding='utf-8') as f:
            self.content = f.read()
        return self.content

    def write(self, new_content):
        """Write new content to the file."""
        with open(self.file_path, 'w', encoding='utf-8') as f:
            f.write(new_content)
        self.content = new_content

    def print_properties(self):
        """Print all file system properties to console."""
        st = os.stat(self.file_path)
        print(f"File Name: {self.file_path.name}")
        print(f"File Path: {str(self.file_path.absolute())}")
        print(f"Size: {st.st_size} bytes")
        print(f"Creation Time: {time.ctime(st.st_ctime)}")
        print(f"Last Modified Time: {time.ctime(st.st_mtime)}")
        print(f"Last Access Time: {time.ctime(st.st_atime)}")
        attributes = []
        if st.st_mode & stat.S_IRUSR: attributes.append("Readable")
        if st.st_mode & stat.S_IWUSR: attributes.append("Writable")
        if st.st_mode & stat.S_IXUSR: attributes.append("Executable")
        if st.st_mode & stat.S_IFDIR: attributes.append("Directory")
        if os.path.islink(self.file_path): attributes.append("Symlink")
        print(f"Attributes: {', '.join(attributes) or 'None'}")

# Example usage:
# handler = PSM1Handler('example.psm1')
# handler.read()
# handler.print_properties()
# handler.write('New content')

5. Java class that can open any file of format .PSM1 and decode read and write and print to console all the properties from the above list

Here's a Java class using java.nio.file to handle the file. It reads/decodes content as UTF-8, allows writing, and prints properties.

import java.io.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;
import java.nio.file.attribute.*;
import java.time.Instant;

public class PSM1Handler {
    private Path filePath;
    private String content;

    public PSM1Handler(String filePathStr) throws IOException {
        this.filePath = Paths.get(filePathStr);
        if (!filePathStr.toLowerCase().endsWith(".psm1")) {
            throw new IllegalArgumentException("File must have .psm1 extension");
        }
    }

    public String read() throws IOException {
        byte[] bytes = Files.readAllBytes(filePath);
        content = new String(bytes, StandardCharsets.UTF_8);
        return content;
    }

    public void write(String newContent) throws IOException {
        Files.write(filePath, newContent.getBytes(StandardCharsets.UTF_8));
        content = newContent;
    }

    public void printProperties() throws IOException {
        BasicFileAttributes attrs = Files.readAttributes(filePath, BasicFileAttributes.class);
        System.out.println("File Name: " + filePath.getFileName());
        System.out.println("File Path: " + filePath.toAbsolutePath());
        System.out.println("Size: " + attrs.size() + " bytes");
        System.out.println("Creation Time: " + Instant.ofEpochMilli(attrs.creationTime().toMillis()));
        System.out.println("Last Modified Time: " + Instant.ofEpochMilli(attrs.lastModifiedTime().toMillis()));
        System.out.println("Last Access Time: " + Instant.ofEpochMilli(attrs.lastAccessTime().toMillis()));
        String attributes = "";
        if (Files.isReadable(filePath)) attributes += "Readable, ";
        if (Files.isWritable(filePath)) attributes += "Writable, ";
        if (Files.isExecutable(filePath)) attributes += "Executable, ";
        if (Files.isHidden(filePath)) attributes += "Hidden, ";
        if (Files.isSymbolicLink(filePath)) attributes += "Symlink, ";
        System.out.println("Attributes: " + (attributes.isEmpty() ? "None" : attributes.trim().replaceAll(",$", "")));
    }

    // Example usage:
    // public static void main(String[] args) throws IOException {
    //     PSM1Handler handler = new PSM1Handler("example.psm1");
    //     handler.read();
    //     handler.printProperties();
    //     handler.write("New content");
    // }
}

6. Javascript class that can open any file of format .PSM1 and decode read and write and print to console all the properties from the above list

Here's a JavaScript class for Node.js (using fs module). It reads/decodes as UTF-8, allows writing, and prints properties. Run with Node.js.

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

class PSM1Handler {
    constructor(filePath) {
        this.filePath = path.resolve(filePath);
        if (!this.filePath.toLowerCase().endsWith('.psm1')) {
            throw new Error('File must have .psm1 extension');
        }
        this.content = null;
    }

    read() {
        this.content = fs.readFileSync(this.filePath, 'utf-8');
        return this.content;
    }

    write(newContent) {
        fs.writeFileSync(this.filePath, newContent, 'utf-8');
        this.content = newContent;
    }

    printProperties() {
        const stats = fs.statSync(this.filePath);
        console.log(`File Name: ${path.basename(this.filePath)}`);
        console.log(`File Path: ${this.filePath}`);
        console.log(`Size: ${stats.size} bytes`);
        console.log(`Creation Time: ${stats.birthtime}`);
        console.log(`Last Modified Time: ${stats.mtime}`);
        console.log(`Last Access Time: ${stats.atime}`);
        let attributes = [];
        if (stats.mode & fs.constants.S_IRUSR) attributes.push('Readable');
        if (stats.mode & fs.constants.S_IWUSR) attributes.push('Writable');
        if (stats.mode & fs.constants.S_IXUSR) attributes.push('Executable');
        console.log(`Attributes: ${attributes.length ? attributes.join(', ') : 'None'}`);
    }
}

// Example usage:
// const handler = new PSM1Handler('example.psm1');
// handler.read();
// handler.printProperties();
// handler.write('New content');

7. Write a c class that can open any file of format .PSM1 and decode read and write and print to console all the properties from the above list

Here's a C++ class using <fstream>, <sys/stat.h>, and <ctime> (portable across platforms). It reads/decodes as UTF-8 (assumed), allows writing, and prints properties.

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

class PSM1Handler {
private:
    std::string filePath;
    std::string content;

public:
    PSM1Handler(const std::string& fp) : filePath(fp) {
        if (filePath.size() < 5 || strcasecmp(filePath.substr(filePath.size() - 5).c_str(), ".psm1") != 0) {
            throw std::invalid_argument("File must have .psm1 extension");
        }
    }

    std::string read() {
        std::ifstream file(filePath, std::ios::in | std::ios::binary);
        if (!file) throw std::runtime_error("Cannot open file");
        content.assign((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
        return content;
    }

    void write(const std::string& newContent) {
        std::ofstream file(filePath, std::ios::out | std::ios::binary);
        if (!file) throw std::runtime_error("Cannot write to file");
        file << newContent;
        content = newContent;
    }

    void printProperties() {
        struct stat st;
        if (stat(filePath.c_str(), &st) != 0) {
            throw std::runtime_error("Cannot get file stats");
        }
        std::cout << "File Name: " << filePath.substr(filePath.find_last_of("/\\") + 1) << std::endl;
        std::cout << "File Path: " << filePath << std::endl;
        std::cout << "Size: " << st.st_size << " bytes" << std::endl;
        std::cout << "Creation Time: " << std::ctime(&st.st_ctime);
        std::cout << "Last Modified Time: " << std::ctime(&st.st_mtime);
        std::cout << "Last Access Time: " << std::ctime(&st.st_atime);
        std::string attributes;
        if (st.st_mode & S_IRUSR) attributes += "Readable, ";
        if (st.st_mode & S_IWUSR) attributes += "Writable, ";
        if (st.st_mode & S_IXUSR) attributes += "Executable, ";
        if (attributes.empty()) attributes = "None";
        else attributes = attributes.substr(0, attributes.size() - 2);
        std::cout << "Attributes: " << attributes << std::endl;
    }
};

// Example usage:
// int main() {
//     try {
//         PSM1Handler handler("example.psm1");
//         handler.read();
//         handler.printProperties();
//         handler.write("New content");
//     } catch (const std::exception& e) {
//         std::cerr << e.what() << std::endl;
//     }
//     return 0;
// }