Retrieving dll path of a running process - scripting

I have an application that uses a .dll file, there are 2 different locations for the file and I need to find out which one it is using on over 200 machines.
I am very new to power shell and have tried Get-Process method but it does not supply the information I need, is there another way to retrieve this in power shell?

This article gives one approach using a WMI provider call. You could use the provided Function at the end. If your just looking for something quick and dirty this would work.
Digging in a little more, This might be what you want:
$modules = Get-Process | Where { $_.ProcessName -eq "process.name" } | Select Modules
$modules.Modules
Replace process.name with your process name

The DLLs for a process are contained in the Modules property of the Process object returned by Get-Process.
Get-Process notepad| select -ExpandProperty modules| Format-Table -AutoSize
To look for a specific DLL, you could do something like this:
Get-Process chrome|
select -ExpandProperty modules|
foreach { if($_.ModuleName -eq 'pdf.dll'){$_.Filename} }
Since there could be many processes with the same name, you could use this to show only the distinct DLL locations:
Get-Process chrome|
select -ExpandProperty modules|
where {$_.ModuleName -eq 'pdf.dll'}|
group -Property FileName|
select name

I wrote an article a while back on how to find DLLs that were loaded by a particular process. You can probably adapt this code to find your specific DLL.
http://trevorsullivan.net/2010/08/25/powershell-finding-currently-loaded-dlls/

Related

Change Visual Studio project property Start action to "Don't open page" in several projects

When I first download our solution from the version control server, I need to set every project Start action property manually. I would like to know if there is any 'unattended' way to do this. I don't mind creating a batch or powershell script, even opening every needed file and search and replace, assuming this property would be in plain text. I wasn't able to find it in the vbproj file.
In vbproj.user the property is <StartAction>, you must change it's value to NoStartPage.
I ended up putting together a powershell script (based on other answers at stackOverflow) to help me out with that.
gci -r -include "*.vbproj.user" |
foreach-object { $a = $_.fullname; ( get-content $a ) |
foreach-object { $_ -replace "(?<=<StartAction>).*(?=<\/StartAction>)", "NoStartPage" } |
set-content $a }

BAT or Powershell For loop through CSV to build a URL

Solved. So my first go at this post was a VERY poorly structured question trying to obfuscate proprietary company information in a very poor manner, and not asking the question well.
Once Walter even got me thinking in the correct direction i worked through the issue. Below was the second issue i was running into and found that the #{key=value} statement was being passed into my url because for some reason my script did not like the header in my csv file. In hindsight, perhaps because i was naming my variable the same as my header. Regardless I worked around it just by using Get-Content rather than Import-CSV.
$aliases = Import-Csv -Path .\aliases.csv
foreach ($alias in $aliases) {
Write-Output ('http://www.' + $($alias) + '.mydomain.com') >> urls.txt
where the contents of aliases.csv is:
alias
Matthew
Mable
Mark
Mary
This is giving me:
http://www.#{alias=Matthew}.mydomain.com
http://www.#{alias=Mable}.mydomain.com
http://www.#{alias=Mark}.mydomain.com
http://www.#{alias=Mary}.mydomain.com
When successful urls.txt should contain:
http://www.Matthew.mydomain.com
http://www.Mable.mydomain.com
http://www.Mark.mydomain.com
http://www.Mary.mydomain.com
NOTE: Edited to clarify use case
In Powershell
Get-Content names.txt | %{"Hello, my name is $_. How are you?"} >> results.txt
By the way, with just a little more effort, you can read more than one variable from a csv file, and substitute all of them for named variables in the text. This turns out to be very useful in a variety of situations.
Edit to conform to your edit
Import-csv ./aliases.csv | %{ "http://www.$($_.alias).mydomain.com"}
Notes:
Once you get used to them, pipelines are the easiest way to process a stream of just about anything.
% is an abbreviation of Foreach-Object (not to be confused with foreach).
The loop will be done once for each object coming out of the pipe. Each object will be a PSCustomObject with a single property named alias.
$() allows evaluation of a subexpression within a double quoted string.
$_ is the current object.
the dot, in this context, separates an object specified from a named property.

Changing a string in an .exe file

I would like to know how to change a String in an .exe file. It is a list of 8 files which have all the same Content but are used in diferent paths. And These paths (Folders) are named 1-8. And now I have to Change that string ("word class 1") into 2-8 ("word class 2, ...") I did it manually with Notepad++ for a week now but it's time consuming and I don't want to do it anymore with Notepad++. :)
I don't mind any way of a solution to this Problem so, that's it.
I tried it with powershell so far but I can't figure out how to get the solution done with the get-content & select_string but it didn't work out as intended.
Thank you for reading and answering my question. (sorry for some typos)
You just want to replace some values within a .exe?
This is how I'd do it.
You need to provide a CSV file, first column titled OLD, second column titled new.
Here is my fake .exe file I made:
7deeadc7-a2b3-4c47-8cf6-61f09d986977ham
d1ea8982-4a04-4f2b-8e5a-244965921fccsam
b4a8f37a-c607-405b-8493-9b9b0e79673btam
0922496b-3064-4958-a6b0-46f61a711860turkey
e5f30554-e50e-4b61-aaa3-3797d9e0ed5ccheese
82e3d77f-53d5-49ef-bf84-b872dbbe556ffork
60a01cad-f6c4-44cc-af1a-fafb20377a12rice
e2cd71a1-7c34-456f-9af4-924f79874c38yummy
c85da055-c47e-41be-a0f8-5c320fa05317linux
7dbee5fc-87d5-4900-80c5-00818514d5b4morp
d9941dfe-dd97-422d-9088-2cecf4904fdepoo
05eaf9b3-09a2-45ea-b9a0-4c78ff9156f2pot
8c75d00d-4157-45b9-86df-74226790674fpoe
f0e77eb5-35fa-47f5-b89e-d1b5ef3c726fpoh
1d1ffc02-fee0-446d-aeac-940ab2864a76pof
Just a bunch of guids with a word at the end. Now, Here's my sample .csv file, with all of the replacements we want to make.
OLD,NEW
ham,pork
sam,Frodo
linux,Window
morp,porp
poo,restroom
Finally, here is the code to do this as a PowerShell Function.
Function Refresh-File {
param($inputCSV,$inputfile)
$file = get-content $inputfile
Foreach ($replacement in (Import-csv $inputCSV)){
$file = $file -replace $replacement.old,$replacement.New
}
$file | set-content $inputfile
}
Call it like this: Refresh-File -inputCSV T:\replace.csv -inputfile T:\blah.exe
Here's my .exe file after running this, just the value portions, to show you that it worked:
pork
Frodo
tam
turkey
cheese
fork
rice
yummy
Window
porp
restroom
pot
poe
poh
pof
Since you'll want to automate this, simply make a new replacement.csv file everyday. Then run this code. If you've never written a full PS1 script file before, as a quick summary, copy the function, paste it into notepad or the PowerShell ISE, and then at the last line of the script, put the command syntax to call the function. Save and enjoy.

Extract function signatures from the Office VBA Object Models?

Is there a way to extract function/property data from the Object Library binaries (eg, the Microsoft Access Object 14.0 Library which is typically located at C:\Program Files\Microsoft Office\Office14\MSACC.OLB)?
I'm not interested in the implementation details, I just want to be able to extract the public interfaces - something along the lines of:
Class: TextBox
Properties:
Property Get BackColor() As Long
Property Let BackColor(value As Long)
... (etc)
Functions:
Sub Move(Left, [Top], [Width], [Height])
... (etc)
Events:
Event AfterUpdate()
Event BeforeUpdate(Cancel As Integer)
... (etc)
The exact formatting is not important - I just need a text dump of this data in any format (I'll then write a program around it to parse it). In the C++ world this would essentially be an extract of the header files.
Presumably this is something the Object Explorer within the VBE already does (and the AutoComplete, and any other program capable of reading *.olb files), unfortunately I don't even know where to start here (Googling "extract from olb file" / "read olb file" hasn't yielded any useful results). Can anyone offer any advice with this?
You can easily do that with PowerShell. The syntax is:
New-Object -ComObject <com object>
To list all properties in Excel.Application we use Get-Member:
New-Object -ComObject Excel.Application | Get-member
To export the list in a text file:
New-Object -ComObject Excel.Application | Get-member | Format-Table -Wrap -Autosize | Out-File list.txt
Edit:
COM Object are registered in HKEY_LOCAL_MACHINE\SOFTWARE\Classes
get-ChildItem "REGISTRY::HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Excel.*" | foreach-object {New-Object -ComObject $_.pschildname | Get-member | Format-Table -Wrap -Autosize | Out-File $($_.pschildName + ".txt") }
This command will list all COM Objects whose name starts with Excel. and print their respective properties in a file named <com object>.txt.
Microsoft had a utility called "oleview.exe" which was certainly available in year 2003. It can open a '.OLB' file file, and dump it in a text format. I have a copy of oleview and it still runs fine on Windows 10. It also needs a associated DLL called "iviewers.dll". I don't know where it can be downloaded these days, so try Googling. It may have been supplied with Visual Studio.

What's the best way to change the namespace of a highly referenced class?

I am attempting to move a highly referenced class from one namespace to another. Simply moving the file into the new project which has a different root namespace results in over 1100 errors throughout my solution.
Some references to the class involve fully qualified namescape referencing and others involve the importing of the namespace.
I have tried using a refactoring tool (Refactor Pro) to rename the namespace, in the hope all references to the class would change, but this resulted in the aforementioned problem.
Anyone have ideas of how to tackle this challenge without needing to drill into every file manually and changing the fully qualified namespace or importing the new one if it doesn't exist already?
Thanks.
Try to use Resharper. I have used it in the past for refactoring highly referenced namespaces both fully qualified and imported with no problems at all.
Here's a Powershell script that I have used to accomplish a painful namespace rename. In my situation there were about 5000 VB.Net and C# source files making heavy use of a common library (CSLA). For reasons not worth discussing, I needed to rename the namespace Csla to CslaLegacy. With minimal effort, you should be able to adapt this script to your specific needs. The script recursively searches the source tree looking for .vb and .cs files. The $repValues hash table contains the strings that need to be replaced. A variation of this script can also be used to update project references, should your rename include an assembly name change. You can add a call to your source control tool to checkout the file before the modification. I originally did this for TFS, but found it slow to execute tf.exe. In the end it was much faster to simply checkout the entire source tree before running the script. I use PowerGUI script editor for debugging and running powershell scripts.
$root = "c:/path/to/your/source"
cd $root
$files = Get-ChildItem -Path $root -Recurse -include *.cs,*.vb
$repValues =
#{
'using Csla;' = 'using CslaLegacy;';
'using Csla.Validation;' = 'using CslaLegacy.Validation;';
'using Csla.Data;' = 'using CslaLegacy.Data;';
'Imports Csla' = 'Imports CslaLegacy';
'Imports Csla.Validation' = 'Imports CslaLegacy.Validation';
}
$stmtsToReplace = #()
foreach ($key in $repValues.Keys) { $stmtsToReplace += $null }
$repValues.Keys.CopyTo($stmtsToReplace, 0)
foreach ($file in $files)
{
$path = [IO.Path]::Combine($file.DirectoryName, $file.Name)
$sel = Select-String -Pattern $stmtsToReplace -Path $path -l
if ($sel -ne $null)
{
write "Modifying file $path"
(Get-Content -Encoding Ascii $path) |
ForEach-Object {
$containsStmt = $false
foreach ($key in $repValues.Keys)
{
if ($_.Contains($key))
{
$_.Replace($key, $repValues[$key])
$containsStmt = $true
break
}
}
if (!$containsStmt) { $_ }
} |
Set-Content -Encoding Ascii $path
}
}
I don't if it's going to be helpful in your case.
Modify the namespace, VS IDE will show you little red rectangular at the end of the namespace.
Press Ctrl+. and select the option you like most.
If you're using tool like ReSharper, click on the namespace and press Ctrl+R. Follow instruction in Rename Namespace dialog box.
It seems like you shouldn't run into too much trouble doing a global search and replace on the fully qualified name. So do a search-for-all on oldspace::myclass and replace it with newspace::myclass. Adding lines to the top of a file isn't terribly hard either, and you could probably replace
using oldspace;
with
using oldspace;
using newspace;
There are some risks with an approach like this, of course. It's quite easy to cause yourself subtle problems.
Another reason to switch to c sharp. Refactoring of source code built in for free in VS 2008.