Create a solution file for Visual Studio with a clean architecture.
This PowerShell script automates the creation of a Visual Studio solution structure with multiple projects, including a UI project (WPF, WinUI, or MAUI) and associated class libraries. It sets up a standard folder layout and configures project references. The script is designed to streamline the initial setup of a .NET solution, saving time and ensuring consistency across projects.
- Creates a solution folder with a
srcsubfolder. - Generates three class library projects:
Domain,Core, andInfrastructure. - Generates a UI project based on user selection (WPF).
- .NET SDK installed and
dotnetavailable on PATH.
There are a few simple options to make the script available from any location. This repository includes an installer script install.ps1 that automates common steps.
Quick installer examples
- Install (default): add
%USERPROFILE%\Scriptsto your user PATH. If you runinstall.ps1with no action flags it will default to-AddToPath(and currently also sets the-CreateProfileFunctionflag by default).
.\install.ps1 or from repo root:
.\install.ps1 (adjust path as needed)
- Install + request a wrapper function to be added to your PowerShell profile (note: the installer exposes
-CreateProfileFunction, but the current implementation does not create the wrapper automatically):
.\install.ps1 -AddToPath -CreateProfileFunction
- Install as a simple PowerShell module:
.\install.ps1 -AsModule
- Remove everything added by the installer (script, shim entry removal logic, module, PATH entry, and profile wrapper removal logic):
.\install.ps1 -Delete
Notes about what the installer does (current behavior)
- Default behavior: when called without action switches the installer will perform
-AddToPath. The script also sets-CreateProfileFunctionby default in the parameter handling, but the wrapper creation is not implemented in the current script. - It copies
Create-VSSolution.ps1into the install folder (default:%USERPROFILE%\Scripts) when the source script is available in the repository. - The installer exposes flags and removal logic for a
Create-VSSolution.cmdshim and a PowerShell profile wrapper. However, the current implementation does not create the shim or the profile wrapper; the-Deleteand-DeleteProfileFunctionflags attempt to remove wrapper/shim artifacts if they already exist. - It can install the script as a minimal PowerShell module under
%USERPROFILE%\Documents\PowerShell\Modules\Create-VSSolution\when-AsModuleis used. - It supports
-Forceto overwrite existing files without prompting (when the copy logic runs it respects-Force). - The installer has a
-VerboseModeparameter controlling informational output (numeric verbosity levels).
Using the wrapper or shim
- PowerShell wrapper: if you add a wrapper to your profile manually, reload your profile (
. $PROFILE) or restart PowerShell, then run:
Create-VSSolution
- CMD/shim: if you create a shim manually and add the install folder to your PATH you can run from any shell:
Create-VSSolution
Troubleshooting and environment
- If you downloaded the script from the internet, unblock it first:
Unblock-File .\Create-VSSolution.ps1 - Ensure execution policy allows running scripts:
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned - If PATH changes don't appear in an open shell, either restart the shell or add the folder to the session manually:
$env:Path += ';' + "$env:USERPROFILE\Scripts"
The projects created by the script use a default TFM. To change the TFM (for example from net6.0 to net7.0), you have several options:
- Edit the script before running
- Open
src\Create-VSSolution.ps1and look for the variable that sets the TFM (commonly something like$TFM = 'net6.0'). Change it to the desired TFM (for example'net7.0').
- Use the
-f/--frameworkoption when usingdotnet newdirectly
- When creating projects manually, pass the framework to the template:
dotnet new classlib -f net7.0 -o MyLib.
- Change TFMs for generated projects after creation (bulk replace)
- Run a PowerShell replace over the generated project files. Example to replace
net6.0withnet7.0:
Get-ChildItem -Path . -Recurse -Filter *.csproj | ForEach-Object { (Get-Content $_.FullName) -replace 'net6.0', 'net7.0' | Set-Content $_.FullName }
- Alternatively, use
sed/perlor an editor to update the<TargetFramework>element in each.csproj.
Notes
- Ensure all referenced libraries and NuGet packages support the target TFM you choose.
- After changing TFMs, run
dotnet restoreanddotnet buildto validate everything compiles.
The generator script is located at src\Create-VSSolution.ps1. You can run it directly from the repository or after installing it with install.ps1.
Prerequisites
- .NET SDK installed and
dotnetavailable on PATH. - On Windows, additional templates may be required for WPF/WinUI projects (Windows App SDK / WinUI templates).
- Ensure execution policy allows running local scripts:
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned.
Run the script directly (no install)
- From the repository root:
& "Create-VSSolution.ps1" -SolutionName MyApp -ProjectType wpf
- From the
srcfolder:
& ".\src\Create-VSSolution.ps1" -SolutionName MyApp -ProjectType wpf
Installed usage (recommended)
- If you used
install.ps1 -AddToPath(the default installer behavior), you can run the installed script after adding\Scriptsfolder to PATH:
Create-VSSolution -SolutionName MyApp -ProjectType wpf
- If you prefer a cross-shell command and create a shim manually in the install folder, the shim would let you call the same
Create-VSSolutioncommand from cmd.exe or other shells once the install folder is on PATH.
Parameters for install.ps1
-InstallPath(default:%USERPROFILE%\\Scripts): Destination folder for the script and any shims.-AddToPath: AddInstallPathto the user's PATH environment variable.-CreateProfileFunction: Flag exposed by the installer to request a wrapper function in the PowerShell profile (currently not implemented).-DeleteProfileFunction: Flag to remove a profile wrapper if present.-Delete: Remove installed script, module folder, PATH entry and profile wrapper lines (best-effort removal behavior).-AsModule: InstallCreate-VSSolution.ps1as a simple PowerShell module underDocuments\PowerShell\Modules\Create-VSSolution.-Force: Overwrite existing files without prompting when copying.-VerboseMode: Numeric verbosity level for installer output (0..n).
Examples
-
Add the scripts folder to user PATH (default behavior when called with no action switches):
.\install.ps1 -
Install as a module (overwrite existing module files if needed):
.\install.ps1 -AsModule -Force
Notes
- The script uses
net8.0by default for generated projects. Editsrc\Create-VSSolution.ps1to change the TFM. - After installing with
-CreateProfileFunction(once wrapper creation is implemented), reload your profile (. $PROFILE) or restart PowerShell to use the wrapper immediately.
Troubleshooting
- If a
dotnet newtemplate fails, install the required SDKs/templates and restart your shell. - If commands still fail due to script blocking, run
Unblock-Fileon the script and set an appropriate execution policy.
Contributions are welcome. Please follow the guidelines in CONTRIBUTING.md and open issues or pull requests.
See CONTRIBUTING.md
- Go to the Issues page: GitHub Issues
- Click "New Issue" and provide steps to reproduce, expected behavior, actual behavior, environment, and attachments (logs/screenshots).
Distributed under the AGPL-3.0 License. See LICENSE.txt or license link.
Jens Tirsvad Nielsen - LinkedIn
Thanks to contributors and the open-source community.

