thedev
thedev

Reputation: 2906

Create network share on machine outside domain

Issue:

Create a network share on a remote machine (Win 2008 Server) from a .ps1 script and provide username and password.

This works fine where the current user has enough privileges

$share = Get-WmiObject Win32_Share -List -ComputerName 10.0.0.1
$share.create("C:\dir","foo", 0)

When targetServer is a machine where my user does not have enough privileges I need a way to provide the username and password

Upvotes: 1

Views: 128

Answers (1)

Ansgar Wiechers
Ansgar Wiechers

Reputation: 200293

Get-WmiObject has a parameter -Credential, so you can use Get-Credential to prompt the user for credentials and pass them like this:

$cred  = Get-Credential
$share = Get-WmiObject Win32_Share -List -Computer 10.0.0.1 -Credential $cred
$share.Create('C:\dir', 'foo', 0)

If you want to fully automate credential handling, you can build a credential object yourself:

$username = 'DOMAIN\user'
$password = 'password'

$pw   = ConvertTo-SecureString $password -AsPlainText -Force
$cred = New-Object Management.Automation.PSCredential $username, $pw

$share = Get-WmiObject Win32_Share -List -Computer 10.0.0.1 -Credential $cred
$share.Create('C:\dir', 'foo', 0)

Storing plaintext passwords in a script is not a good practice, though, so you may want to store the encrypted password in a separate file (make sure to set restrictive permissions on that file):

PS C:\> Read-Host 'Enter password' -AsSecureString |
>> ConvertFrom-SecureString | Out-File 'C:\password.txt'
>>
Enter password: ******
PS C:\> Get-Content 'C:\password.txt'
01000000d08c9ddf0115d1118c7a00c04fc297eb01000000a04a09e406c93741865ab010ed072699
0000000002000000000003660000c00000001000000028b14f21c501cdf629b94cea2837e8520000
000004800000a0000000100000002db774b0a8612917224e7dbfd69055340800000043f449c82f47
3e78140000007de59fcec57a1dc9b6b62272eff517b8bf5291e5

The encrypted password can then be read and decrypted like this:

$username = 'DOMAIN\user'

$pw   = Get-Content 'C:\password.txt' | ConvertTo-SecureString
$cred = New-Object Management.Automation.PSCredential $username, $pw

$share = Get-WmiObject Win32_Share -List -Computer 10.0.0.1 -Credential $cred
$share.Create('C:\dir', 'foo', 0)

Note, however, that ConvertTo-SecureString encrypts/decrypts the password with the user (and I think the host) running the command. If you need to encrypt the password as one user and decrypt it as another user (or on another host) you must share a key between those users/hosts. A random key can be generated like this:

PS C:\> $numchars = 24   # 192 Bit
PS C:\> $charmap = [char]'A'..[char]'Z' +
>> [char]'a'..[char]'z' +
>> [char]'0'..[char]'9'
>>
PS C:\> [char[]]($charmap | sort {Get-Random})[1..$numchars] -join ''
b69cGXKpJaI5tLrj4lHEPN3e

Create the password file with a shared key like this:

PS C:\> $key = [char[]]($charmap | sort {Get-Random})[1..$numchars] -join ''
PS C:\> $pw = Read-Host 'Enter password' -AsSecureString |
>> ConvertFrom-SecureString -Key ([byte[]][char[]]$key)
>>
Enter password: ******
PS C:\> @"
>> Key  = $key
>> Pass = $pw
>> "@ | Out-File 'C:\password.txt'
>>

and read the encrypted password like this:

$username = 'DOMAIN\user'

$pass = Get-Content 'C:\password.txt' | Out-String | ConvertFrom-StringData
$pw   = ConvertTo-SecureString $pass.Pass -Key ([byte[]][char[]]$pass.Key)
$cred = New-Object Management.Automation.PSCredential $username, $pw

$share = Get-WmiObject Win32_Share -List -Computer 10.0.0.1 -Credential $cred
$share.Create('C:\dir', 'foo', 0)

Upvotes: 1

Related Questions