Find out WHO made the last change to files by Powershell? - windows

I have a shared network location for all users saving files. All users have full access to this location.
Is that possible to find out WHO made the last change to a file or folder by Powershell or any other way?
There is no issue to get all those date and owner info from Powershell, but looks like there is no way to find out WHO made the last changes.
any idea please?

The only user held against a file on NTFS is the owner. There is no record of who last modified the file.
However Windows can audit file system operations.
See http://support.microsoft.com/en-us/kb/310399 (says Windows XP in the title but applies to later versions). This needs to be applied to the system hosting the file system.

Related

Preventing Powershell from adopting Windows Explorer options

I don't do much with Powershell often but yesterday was needing to extract a file from a zip archive. During the process I was looking for a file by iterating through the contents of a zip anbd comparing the file's (item) Name property to the filename (say abc.ps1).
Code was working locally and I was happy with the result I was getting.
Pushe the code to deployment environment to be run on server and the code was notifying me that it could not find abc.ps1.
Further investigation, I logged onto the server (as my own account, not the service account that the code executed as). When I looked in the zip it was querying I could see the file, but it was named abc.
I had xyz.txt and def.pdf but the ps1 file was simply abc. I knew that this is based on an Option in Windows Explorer options for 'Hide extensions for known file types'.
Logging on to the server with the service account, unchecking this option and re-running the script fixed all problems, it was able to fid the file based on name + ext.
Is there a way of enforcing PS not to take into account Explorer options such as these when running?
Am currently thinking of applying a GPO to prevent any systems from having this option on.

Maven reads user configuration from wrong location

I just discovered why Maven doesn't work properly on my machine. For some reason it reads the user configuration from the completely wrong location. And I don't understand why. When I run maven with the -X switch I get the following output in the beginning:
[DEBUG] Reading global settings from D:\dev\maven\active\conf\settings.xml
[DEBUG] Reading user settings from D:\.m2\settings.xml
[DEBUG] Using local repository at D:\dev\maven_repo
Why is it reading user settings from D:\.m2 and not my actual user directory like it normally should? It worked fine on my old computer. Does it have something to do with me having installed maven on a different drive this time? On my old computer it was installed on the C drive.
Where does it get this D:\.m2 from? How can I make it read the user settings file from the actual default location, %userprofile%\.m2?
Finally figured it out. Found the solution in this blog post. To find the home directory in Java you do this:
System.getProperty("user.home");
Problem is, for some dumb reason, Java isn't using Windows environment variables or anything like that to find this path. It actually uses the parent directory of the Desktop directory. Since I like to keep certain main folders in my user directory on a separate drive (documents, downloads, music, desktop, etc) I had moved the desktop directory to D:\Desktop. Java then takes that directory, goes one level up and makes Maven and other java applications think D:\ is my home directory.
Gotta say the more I use Java the more i hate it... anyways, hopefully this might help save some hours of head scratching for someone else too.
Update
The original blog post is gone, but found on the WaybackMachine (the URL has been updated), but here's the gist from that post in case that goes too...
The issue: So how does Java play into all of this? Well, Java
developers sometimes want to store settings for their applications in
a folder within the user’s profile directory. It’s the Linux way, and
Java tends to do things the Linux way. (As mentioned earlier, Windows’
“AppData” folder servers the same purpose, with some extra separation
for data dependent on whether or not it should roam with the user’s
profile.) For some reason, Java does not use the Windows environment
variable to determine the location of the user’s profile, but instead
access a registry key that references the user’s desktop folder. It
then takes the parent directory of the desktop and assumes that is the
user’s profile folder (assuming the user makes use of the default
setup Windows chooses).
Essentially, when a programmer calls the Java command:
System.getProperty("user.home");
Java uses the following idea to determine where my user profile folder
is:
PATH_TO_DESKTOP_FOLDER_AS_SET_IN_THE_REGISTRY + "\..\"
This breaks down when the desktop folder has been modified.
So, with my setup, instead of saving settings at:
c:\users\tim\
Java apps tend to save data to:
t:\tim\
In reality, Java apps should save settings to:
c:\users\tim\AppData\Roaming\
or something like that.
To add insult to injury, the Java apps continue to follow the Linux
way and use a period at the beginning of the folder name in an attempt
to “hide” the folder (as is done on Linux). For Windows users, this
simply ensures these folders are listed first in directory listings.
(Hiding a folder on Windows is achieved through setting the hidden
attribute for the file.)
It looks like NetBeans has addressed the issue for their application,
but the root issue remains an unresolved, low priority bug. Somehow
I’d bet it would get fixed a lot faster if the mechanism for
determining the user’s home path on Linux was wrong.

Where should a WinForm app keep its logs?

I am working on a WinForm application, that allows working to work with "projects" (think about the application as Visual Studio, and projects as VS Solutions).
My question is - where should the application keep its logging files?
Some requirements include:
the application might not be running as an administrator (so saving in the %ProgramFiles% installation folder is not a good option)
The logs should be accessible to end-users (either for review, or for sending to the support team). (This means that hard to find folders, like %AppData%\Company\Application\Version\ProjectName... are not a good solution either)
The application might generate logs even when there are no open projects (so saving the logs in the project's folder is good only when there's a project, but not a final solution).
I was thinking of creating a "working folder" when the application is installed - something along the lines of C:\Application\, and then save the logs in a subfolder, like %WorkingFolder%\Logs\ProjectName
Thanks for the input.
Somewhere in the user's directory is actually the correct place to store them if they are specific to the current running user.
Some programs create folders at the top level of the User's directory, next to Documents and Desktop, others do it in Documents.
Creating it in C:\ might cause issues if the user doesn't have write access to the root directory. You can pretty much guarantee the user will have write access to the Home directory.
The other option is to look for an environment variable, and if its set use the value as the location, if not default to the User's home directory.
If the logs are user only you should store them at %AppData%\Company\Application Name.
If the logs are shared (any user can see any log) you should store them at:
%ProgramData%\Company\Application Name (for Vista+)
or
%AllUsersProfile%\Application Data\Company\Application Name (for XP-)
As for user access, you can add a shortcut to the start menu to the appropriate location or have a link within the program.
Another option in Vista+ is the Public folder (%Public%) which has links throughout Explorer for easy access to.
Where should I write program data instead of Program Files is a good blog entry by Chris Jackson from Microsoft. While it isn't an "official stance" it holds some excellent information.
You can always ask the user to configure this. Set a default path, maybe the application directory. During installation or while setting up the application you may prompt the user to input the path they want to use for logs. That's fair, right. If they're advanced enough to use logs they're good enough to configure a path too.
What do you plan to do with the logs. Are they technical, of for financial/security audits?
The EventLog is a nice place for technical logs, because you can access it remotely (within the Domain) and it is cleaned up automatically.
The %AppData% is also a good place for technical logs, specially if you are unable to connect to the eventlog. You can find the log files, and you can direct the end-user to them, but they are not "in the face" of the end-user. You can include a "send log to the maker" button to receive them.
For logs that needs be accessed by end-users, the My Documents (or a subfolder) looks good.
You can just to add button / menu item to easy open folder with logs.
Best place fo logs are %AppData%\AppName or %temp%\AppName.
Never use %MyDocs% or %Program Files%.
I'd suggest adding that question to the installer so that the user that installs the software can decide where best to put the logs. Though C:\[AppName\ sounds like a reasonable default for your requirements.
Edit: Just thought off, it would probably be worth warning the user if the select a bad location (in Program Files or in the root of the system drive etc) and if they choose to create a new directory, automatically give that directory correct permissions during the installation.
I think %APPDATA%\YourCompanyName\YourAppName is the preferred location. To overcome your stated objection of this location being hard to find, you could pretty easily and quickly implement a simple support screen in your app to allow the end user the ability to access and email these logs without too much trouble, so that the user will not have to remember or manually navigate to the long path name to get to the logs.
I don't really like the idea of the user being able to set this location via the installer because of possible naming and permission issues.
If the app needs to maintain the log only for the users current logged in timespan, then you could keep it in c:/temp.
Most of my winapps, i leave it there, so automatically it gets deleted once the user logs off..
Ofcourse, this primarily depends on your requirement.

Where to store an application log file on Windows

Where would be the best "standard" place to put an application's debug log file in a Windows user environment?
In this particular case, it is an application that is run once and could go wrong. It will be run by system administrator types who may need to inspect the log after the application is run. Everytime the application is run, a new log file is created.
Options that have been floated so far include:
The program directory
The user's desktop
The user's local Application Data directory.
I have my favourite, but I wondered what the SO consensus was.
Note: this is similar to this question, but we're dealing with an application that's only likely to be run once by one user.
The Application Data directory would seem to be the perfect place, but it's an area that is nearly invisible. You need to give your users an easy way to get to it.
Have your installation script create a Log folder in the Application Data area for your program, and include a link to the folder in your Start menu.
In the organization I work for we use the (%TEMP% or %TMP%)\CompanyOrProductName\Logs directory
Using %APPDATA% may be problematic with roaming profiles if the logs are numerous or huge : it slows their login process ...
1.The program directory <- not good. Ideally you will only have RX permissions on this folder.
2.The user's desktop <- technically can be done, but I don't like this idea. Polluting desktop... I, as a user, don't like it.
3.The user's local Application Data directory. <- better
My preference is a subdirectory under the program directory (with a clear name like "DebugLog" or something similar). Permissions on that subdirectory should allow creating and writing files ("Change" will be fine)
The "standard" place for the log would be the AppData directory. However, really its up to you where you want to store them. As they are administrator (power users) then there should be no problems storing the logs in the same directory as the application being run. Even in the MyDocuments of the user would be a good shout.
If you EXPECT something to go wrong put it in the user's local Application Data directory.
If you don't and just want to log anyways I might think about really using the temp directory. The reasoning for this is simple. If the application is only run once you will leave trash in the Application Data directory otherwise that nobody will ever need again. In the temp you have at least the CHANCE that it's going to be cleaned up later.
BTW: IMHO the best would be not not create the log AS A FILE at all (log to memory) until something goes wrong. Then you can still offer a dialog where the user selects where to save the log.
Windows Temp Folder
Assuming you want to keep log files around a significant amount of time and they are intended to be used, read I would put the log file in a sub-folder of the user's local application data folder, accessible from windows explorer by typing %localappdata%.
If they are temporary log files, only to be used in the event of system diagnostics then you should put them in the temporary folder, accessible from windows explorer %temp%.

Windows: How can I find the LocalAppData directory for each user on a particular machine?

First, some background:
Our product needs to integrate with the Lotus Notes client by adding or updating a line in the NOTES.INI file.
We don't have a problem if we're dealing with a single-user installation of Notes (i.e. if there are multiple Windows users on the machine, they'll all use the same Notes configuration). In this case, there's a single NOTES.INI file in the Notes installation directory.
However, under a multi-user installation of Notes (where each Windows user has their own Notes configuration), each user has their own NOTES.INI file stored in the user's LocalAppData directory - e.g. C:\Documents and Settings\Username\Local Settings\Application Data\Lotus\Notes.
So here's the problem:
If our product is being installed on a machine with a multi-user installation of the Notes client, we need to be able to update the NOTES.INI file in the profile of each user on that machine.
We can do this by having a program run when users log in, which checks whether that user's NOTES.INI file has been updated yet and if not, updates it. However, the uninstall process for our application needs to be able to reverse these modifications for all users on the machine.
Hence the question: assuming our code is running with local admin rights, is there some way that we can iterate through each user's profile and find their LocalAppData directory so we can make the necessary changes?
Any suggestions greatly appreciated :-)
EDIT 2009-03-25 16:52 GMT:
Looks like I have a possible approach (thanks Martin C):
For each subkey of HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList:
If it's a "real" user (determined somehow):
Remember the subkey name - that's the user's SID
Read the ProfileImagePath value
If the user's Registry hive is not already loaded (i.e. there is no subkey of HKEY_USERS with the appropriate SID):
Enable the SE_BACKUP_NAME and SE_RESTORE_NAME privileges
Load the hive from ProfileImagePath\NtUser.dat using RegLoadKey
Try to find the user's LocalAppData folder using each of the following Registry keys in turn:
HKEY_USERS\<SID>\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
HKEY_USERS\<SID>\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion\Explorer\Shell Folders
Expand environment variables in the resulting path if necessary (presumably just expanding %USERPROFILE% to the ProfileImagePath we got earlier)
Use the path to find the user's NOTES.INI file and make the appropriate changes
If we had to load the hive:
Unload the hive using RegUnLoadKey
I can probably get that coded up, but it seems a tiny bit fragile and there's potentially a number of ways it can go wrong.
Anyone have a more "official" approach?
You can enumerate the sub-keys of
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList
Each subkey contains the "ProfileImagePath", which will point to the base-path of the profile. Dependent on the OS-version and the language setting you can then determine the location of LocalAppData (beware, it is language-dependent!).
Edit: A possible starting point for going further could be
HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\User Shell Folders
Unfortunately this could vary from user to user and HKEY_USERS only contains the keys of users which have loaded profiles. You could try if you could load profiles somehow (maybe one can attach a user's registry somehow if it is not already loaded to HKEY_USERS?).

Resources