I'm confused as to how PowerShell modules work.
I have downloaded and copied a module from a blogger. I've unblocked and extracted the .zip to %USERPROFILE%\Documents\WindowsPowerShell\Modules\SomeModule
In this folder is a .NET assembly that the module uses, but doesn't not contain compiled CmdLets. Instead, the commands are functions in a .psm1 file and a .psd1 file describes the manifest.
If I open PowerShell, the functions are available and work but I want to add my own function, so I have added it, however I cannot see it. I've restarted all PowerShell instances, removed the module and imported it again.
As a test, I renamed an existing, working function. Interestingly, after remove and import the function disappears instead of adopting its new name. If I rename it back (just a single character change) and remove/import then it appears again.
I use help blahblah to list all commands in a set, since they all have the same prefix. The manifest exports all (*) functions. Clearly I don't understand how these type of script modules work, the functions are all listed even after I run Remove-Module! I've written a compiled module before in C# and that worked as expected.
What's going on? Why does renaming a function cause it to vanish? Thanks.
Found it. This line appears in some stuff I overlooked in the .psm1 file.
Export-ModuleMember X, Y, Z
So, I guess the manifest can overrule this or replace the need for it in a script? Who knows. Anyway, hope this helps someone.
Related
I read a lot of the answers here and I can't seem to find what I am looking for. So please bear with me.
Each psm1 is a class.
I have:
Main.ps1
Modules/module01.psm1
Modules/module02.psm1
DLL/dllInQuestion.dll
I am trying to load a dll to use inside module02.psm1. I know that in order to do so I have to require it inside a .psd1. I created a psd1 for module02 and put it in the same folder and imported it like this "Import-Module" before the code but it didn't work.
I also tried to create a psd1 for Main.ps1 but it didn't work.
Can I require (using using module statements and Add-Type) all modules and dll inside a .ps1 script and require it inside a .psd1 for Main.ps1?
Thank you.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I have a DLL file and I want to execute it on Windows. I obtained this DLL file from a challenge site which alleges the DLL should be executed independently.
To run the functions in a DLL, first find out what those functions are using any PE (Portable Executable) analysis program (e.g. Dependency Walker).
Then use RUNDLL32.EXE with this syntax:
RUNDLL32.EXE <dllname>,<entrypoint> <optional arguments>
dllname is the path and name of your dll file, entrypoint is the function name, and optional arguments are the function arguments
You can execute a function defined in a DLL file by using the rundll command. You can explore the functions available by using Dependency Walker.
While many people have pointed out that you can't execute dlls directly and should use rundll32.exe to execute exported functions instead, here is a screenshot of an actual dll file running just like an executable:
While you cannot run dll files directly, I suspect it is possible to run them from another process using a WinAPI function CreateProcess:
https://msdn.microsoft.com/en-us/library/windows/desktop/ms682425(v=vs.85).aspx
DLLs are shared libraries which are used by other windows programs while EXEs are the files which are actually executed and are linked to DLL files so that they can use DLLs. Both are of same format, PE(portable executable or format of machine code in windows in simple words).
In other words EXEs contain the entry point(main) and the DLLs contain the library functions.. You cannot execute a file which just contains library functions you can just use them via other programs.
But still there are programs like rundll32.exe which provides that entry point and some minimal framework required by DLL functions to be called.
The point that I want to make is, you can never execute a DLL file you can just use it's code by providing an entry point through an EXE or some other program.
You can't "execute" a DLL. You can execute functions within the DLL, as explained in the other answers. Although .EXE files and .DLL files are essentially identical in terms of format, the distinguishing feature of an .EXE is that it contains a designated "entry point" to go and do the thing the EXE was created to do. DLLs actually have something similar, but the purpose of the "dll main" is just to perform initialization and not fulfill the primary purpose of the DLL; that is for the (presumably) various other functions it contains.
You can execute any of the functions exported by a DLL, assuming you know which one you want to execute; an EXE may contain a whole lot of functions, but one and only one is specially designated to be executed simply by "running" it.
To Run a .dll file..First find out what are functions it is exporting..Dll files will excecute
the functions specified in the Export Category..To know what function it is Exporting refer "filealyzer"
Application..It will show you the export function under "PE EXPORT" Category..Notedown the
function name--
Then open the command prompt,Type Rundll32 dllname,functionname
(dllname--name of your dll)
(Functionname-- name of the function you found under the PE Export)
Note:Makesure that your command prompt location is your dll file location
It should be mentioned that since it is entirely possible to run DLL's just as any other executable, it has long been considered a security issue. As such, there have been a number of security improvements and registry hacks (sorry no longer have ref-links) that prevents running DLL's from regular user space without extra privileges.
As a good example. I recall making these hacks, but since I no longer remember what exactly I did. I can no longer run any DLLs from normal user shell environment, even though starting various Win apps from GUI works just fine.
That said, one should definitely read "Dynamic-Link Library Security" and "Best Practices to Prevent DLL Hijacking".
.DLL files are not executable in the sense that .EXE/.COM/.BAT files are executable, so I'm not sure what you mean.
You can use the Dependency Walker application that comes with the Windows SDK to interrogate a .DLL and see what functions are exported by the file.
The following series of steps might be helpful:
Open Windows Explorer
In the top-left corner, click "Organize"
select "Folder and Search Options"
Switch to the "View" tab
Scroll down and uncheck "Hide file extensions for known file types"
Click OK
Now find the dll file
Right-click on it and select "Rename"
Change the extension(what comes after the last .) and change it to .exe
Everytime i dot source a file in PowerShell it opens a copy of the file in notepad.
Exe:
.\MyScript.ps1
The script runs fine - its just really annoying having these pop up all the time. Is there a way to suppress this?
I'm on windows 7 x64 and using the latest version of PowerShell.
Ex2: This is still launching notepad.
cls
Set-Location "\\PSCWEBP00129\uploadedFiles\psDashboard\"
. .\assets\DCMPull\Powershell\SqlServerTransfer.psm1
. .\assets\DCMPull\Powershell\RunLogging.psm1
You cannot dot source PowerShell files with the .psm1 file extension. One option is to rename them to .ps1.
Alternatively (and, in my opinion the better approach), you can load the PowerShell modules using Import-Module <module.psm1>. Just note that the behavior of Import-Module is different from dot sourcing it. Dot sourcing runs the script in the current scope and also persists all variables, functions, etc.in the current scope. Import-Module does not do that.
Although not very common, you can also export variables from modules with Export-ModuleMember.
Adding to Raziel's answer, there's a lot of thought that went into only being able to dot source files with .ps1 extension, and otherwise why it tries to run it as a system executable. Here's a snippet from PeterWhittaker on GitHub:
. ./afile would only execute something if there's either an
extension-less but executable aFile in the current dir, or a
(not-required-to-be-executable) afile.ps1 file, with the former taking
precedence if both are present; if the file exists, but is neither
executable nor has extension .ps1, it is opened as if it were a
document.
. <filename> with <filename> being a mere name (no path component) by
(security-minded) design only ever looks for a file of that name in
the directories listed in $env:PATH (see below), not in the current
directory.
I encountered exactly the same situation : If the point source imports the .psm1 file, the file will be opened directly instead of importing the code in the file.
Because the function of point source import is only valid in the file with suffix of.ps1, if the suffix does not meet the requirements, it will not be regarded as path, but as a code , so it is like running the corresponding string directly, and the effect is naturally to open the file.
So,this phenomenon is not aimed at .PSM1,if you change the extension to TXT, it will have the same effect. It will have the same effect for any file whose suffix is not .PS1.
You can bypass this problem by creating symbolic links or hard links!
In PowerShell 7, it's easy to create links using New-Item.
I can't recall if this stopped working at some point or has always been this way. When I develop powershell modules I would like to be able to load them explicitly from my local repo directory to make sure everything is working properly. MSDN indicates this should work, however I get the error:
"The specified module .\SomeModule was not loaded because no valid module file was found in any
module directory. FileNotFoundException"
I would expect this is because it can't find the psm1 file in the directory but I can't understand why. I can load the module by referencing the psm1 file directly but this excludes anything being loaded by the manifest. I can also copy the module to one of the standard module paths and it will load correctly. This is what I've been doing as a work around but I'd love to get this figured out. TIA
**Update: Ran process monitor while running the import command. Interesting results. Seems like it may just be a powershell bug.
You can load the module by referencing the module manifest file (.psd1) directly, which will then ensure any dependencies are loaded.
I want to run my working pydev project python code by double clicking the main module (outside of eclipse): xxx.py
The problem is that due to my imports being in different packages:
from src.apackage.amodule import obj
when xxx.py is double clicked it complains it doesn't know where the imports are (even though when I run xxx.py in pydev it magically knows what I'm importing).
A simple workaround is to remove all of the packages and move all of the modules into one directory (that obviously works but is very inconvenient)
How can I run my code in the file system without doing that work around?
This page answers my question excellently:
http://blog.habnab.it/blog/2013/07/21/python-packages-and-you/
Bottom line is always execute your code from the top, highest level, root directory (e.g. using a minimal main.py file that executes the main script of your program). Then, use absolute imports always and you never have a missing module issue since you start the program from the top directory and all imports are based off that 'home' path.
The problem you encountered is the natural behavior of most languages. A programm only knows about its working path (the path it is started in), the paths which are registered in the environment variables and at least relative paths.
The "magic" of the executable you created is therefore: It collects all scripts/modules needed, and copies/combines them next to/in the executable. The Executable then runs within the directory where all other scripts also reside and voila ...
If you are not happy with your workaround of creating an executable every time you want to run your project without PyDev there are two alternatives.
First but not the one I would suggest is registering the working path into in the environment variables.
Second and the one I think is much better: Create a link to the python executable and alter the calling string of the textfield "Target:". Append the path to your script you would like to run. Then alter the textfield "Start in:" and enter the project directory. After you did this you should be able to start your project with a simple double click.
(If you rely on external libraries which are neither on the path nor in you project you could search for appending paths temporarily to the pythonpath via the sys module.)
I hope I could help a bit.