Building PowerShell Module - how to organise your source files and build with ease

แชร์
ฝัง
  • เผยแพร่เมื่อ 17 ธ.ค. 2024

ความคิดเห็น • 13

  • @bharathsimha2822
    @bharathsimha2822 2 ปีที่แล้ว +1

    Thank you for your Today's session 😊

  • @joeltvaldez
    @joeltvaldez 2 ปีที่แล้ว

    Love your work and thank you.

  • @martin-zima
    @martin-zima ปีที่แล้ว

    Hi, thanks for the video (and I can see, taking the time to respond to comments!). For me, the main thing I wanted to understand was *how to organise the files* -- for example...
    [1] I have my own module, some co-workers put the source code for all their functions in the .psm1 file, but I prefer to use 1 file per function (I think like you do), which way is correct/best?...
    [2] Do I need to use a public and private folder (currently I do not)?...
    [3] When to split modules, for example as my module has grown it has functions for different things, currently I have subfolders like "manage-files", "pnp" (for SharePoint online), "utility" (for little UI, helper scripts, etc) -- is using sub folders like this OK, or should I make 3 separate modules? - a "manage-files" module, a pnp one a utility one, etc.
    Thanks again for the video and (hopefully) your help! 👍🏼

    • @kamilpro
      @kamilpro  ปีที่แล้ว +1

      Hey, let me try my best... although please remember these are more conventions than must haves:
      1: .psm1 files are "native" way PowerShell expects module's functions to be loaded - it loads a single file and done, so you get that performance. But for us humans these can get very quickly clanky, plus when more than a single person wants to edit file you might get into (git) conflicts very quickly.
      On the other hand, loose files are what we can nicely understand and keep in version control, but PowerShell doesn't understand these by default, and the only way to make it to "see" other files is by loading them to memory via e.g. dot sourcing.
      What I presented in the video is try to make both sides happy - we write separate ps1 files, then building them into a single psm1 file (although it's really merging text files together). I've seen a lot modules which don't even bother with having a single psm1, and simply load all ps1 flies when module is imported.
      2. Public/Private is convention to easily separate exported functions (public) from not exported (private). Exported functions are the one which user can call after loading a module, and non exported are usable only within module - often helper functions. You can find more here, search for FunctionsToExport: learn.microsoft.com/en-us/powershell/scripting/developer/module/how-to-write-a-powershell-module-manifest?view=powershell-7.3
      3. Modules by definition collect together a number of functions which work together to solve particular problem/manage certain products etc. Therefore it really depends on your use case - e.g. if you have module which create some sort of UI which allows you to manage Sharepoint and possibly upload files to Sharepoint (just trying to make a case on spot of what you provided) then it possibly could be a module for that - as it would try to solve a problem of managing files on Sharepoint via GUI. If all three are doing completing separate thing then I would opt for separate modules. You might even look at so called meta module - a single module which exists only to load other module - if you look for manifest of Az module, you'll see it by itself doesn't have any logic, but requires all other Az.* modules.
      Hope this helps :)

  • @doper6080
    @doper6080 2 ปีที่แล้ว

    @Kamil Pro great video
    Question : How do you use config files with modules , to store configs for a given module

    • @kamilpro
      @kamilpro  2 ปีที่แล้ว

      Hi, can you expand more on your question - configs to be used as per user, or something inside the module to be used only by module?

    • @doper6080
      @doper6080 2 ปีที่แล้ว

      @@kamilpro Thanks for the reply,
      basically I want to hold some values like "db url" "username " and "password"
      So if someone installs my module , they can set those variables once and then the modules can use it

    • @kamilpro
      @kamilpro  2 ปีที่แล้ว

      That’s a good question! I must admit I usually followed the route of creating parameters for things like credentials with [pscredential] type or connection string and left it to the user to provide these - either via console or simply via script.
      But to allow user to actually store these values permanently would require to save the values in a file e.g. in their user profile. The file could be further encrypted so that only user who created file would be able to decrypt it. I believe I’ve seen some modules actually allowing to store config settings, let me have a look and come back to you.

    • @doper6080
      @doper6080 2 ปีที่แล้ว

      @@kamilpro Thanks for the reply , and waiting for further explanation .
      For now I have those credentials , stored as secured string in global variables. Basically made another script , which allows user to set those values. And then all my other scrips and module use those variable. Because these scripts are meant to be used for internal purposes only , haven't faced any conflicts.
      But I believe this is a very risky method. As its highly possible to overwrite those global variables; by mistake or by some other script.

  • @larspedersen5405
    @larspedersen5405 2 ปีที่แล้ว

    Great introduction...
    Question: Can ModuleBuilder be used to define a class in a module that can then be used from a different module?

    • @kamilpro
      @kamilpro  2 ปีที่แล้ว

      You can certainly have classes and enums for your module. By default you are not allowed to access classes from outside of module, but here's what you can do:
      1) You can create a function in your module which creates and returns your class; same applies for $Script: variables.
      2) You can within your module create a variable which creates an instance of the class, and then in your manifest export thet variable
      3) In the script, you can add at the very top (as the first statement) "using module" followed by module name, or path to psm1 file.
      Hope this helps.

  • @ESPViper100
    @ESPViper100 2 ปีที่แล้ว

    Do you know how VariablesToExport is populated? I have several constants that are used by multiple functions, but must also be exported to the PowerShell session that imports the module.

    • @kamilpro
      @kamilpro  2 ปีที่แล้ว

      This one is rather obscure concept, but you can pretty much do what's suggested here: stackoverflow.com/questions/38339377/variables-i-listed-to-export-in-my-powershell-module-manifest-arent-actually-ex
      In essence, set
      - VariablesToExport = '*'
      - in your psm1 file, the variable you're exporting would need to be outside of the function, or you'd need to declare it outside of your function as $Script:var1 and then inside your function assigned value to it like $Script:var1 = "blah"
      - you'd need to add this cmdlet call in your psm1 file: Export-ModuleMember -Variable @("var3", "var4")
      at this point you can access your variables outside the module.
      Although personally whenever I had a need to export certain values to end user, I created a function which would simply return these value (and if needed, additional function to set these values) - this way I could expose internal of module to the user, without worrying of interfere with whatever has been set in session already.
      Hope this helps.