mirror of
https://github.com/StackExchange/dnscontrol.git
synced 2024-05-11 05:55:12 +00:00
@ -254,16 +254,19 @@ var tests = []*TestCase{
|
|||||||
tc("Change back to CNAME", cname("foo", "google.com.")),
|
tc("Change back to CNAME", cname("foo", "google.com.")),
|
||||||
|
|
||||||
//NS
|
//NS
|
||||||
|
tc("Empty"),
|
||||||
tc("NS for subdomain", ns("xyz", "ns2.foo.com.")),
|
tc("NS for subdomain", ns("xyz", "ns2.foo.com.")),
|
||||||
tc("Dual NS for subdomain", ns("xyz", "ns2.foo.com."), ns("xyz", "ns1.foo.com.")),
|
tc("Dual NS for subdomain", ns("xyz", "ns2.foo.com."), ns("xyz", "ns1.foo.com.")),
|
||||||
|
|
||||||
//IDNAs
|
//IDNAs
|
||||||
|
tc("Empty"),
|
||||||
tc("Internationalized name", a("ööö", "1.2.3.4")),
|
tc("Internationalized name", a("ööö", "1.2.3.4")),
|
||||||
tc("Change IDN", a("ööö", "2.2.2.2")),
|
tc("Change IDN", a("ööö", "2.2.2.2")),
|
||||||
tc("Internationalized CNAME Target", cname("a", "ööö.com.")),
|
tc("Internationalized CNAME Target", cname("a", "ööö.com.")),
|
||||||
tc("IDN CNAME AND Target", cname("öoö", "ööö.ööö.")),
|
tc("IDN CNAME AND Target", cname("öoö", "ööö.ööö.")),
|
||||||
|
|
||||||
//MX
|
//MX
|
||||||
|
tc("Empty"),
|
||||||
tc("MX record", mx("@", 5, "foo.com.")),
|
tc("MX record", mx("@", 5, "foo.com.")),
|
||||||
tc("Second MX record, same prio", mx("@", 5, "foo.com."), mx("@", 5, "foo2.com.")),
|
tc("Second MX record, same prio", mx("@", 5, "foo.com."), mx("@", 5, "foo2.com.")),
|
||||||
tc("3 MX", mx("@", 5, "foo.com."), mx("@", 5, "foo2.com."), mx("@", 15, "foo3.com.")),
|
tc("3 MX", mx("@", 5, "foo.com."), mx("@", 5, "foo2.com."), mx("@", 15, "foo3.com.")),
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
},
|
},
|
||||||
"DNSIMPLE": {
|
"DNSIMPLE": {
|
||||||
//16/17: no ns records managable. Not even for subdomains.
|
//16/17: no ns records managable. Not even for subdomains.
|
||||||
"knownFailures": "16,17",
|
"knownFailures": "17,18",
|
||||||
"domain": "$DNSIMPLE_DOMAIN",
|
"domain": "$DNSIMPLE_DOMAIN",
|
||||||
"token": "$DNSIMPLE_TOKEN",
|
"token": "$DNSIMPLE_TOKEN",
|
||||||
"baseurl": "https://api.sandbox.dnsimple.com"
|
"baseurl": "https://api.sandbox.dnsimple.com"
|
||||||
@ -25,5 +25,10 @@
|
|||||||
"domain": "$R53_DOMAIN",
|
"domain": "$R53_DOMAIN",
|
||||||
"KeyId": "$R53_KEY_ID",
|
"KeyId": "$R53_KEY_ID",
|
||||||
"SecretKey": "$R53_KEY"
|
"SecretKey": "$R53_KEY"
|
||||||
|
},
|
||||||
|
"ACTIVEDIRECTORY_PS":{
|
||||||
|
"knownFailures": "17,18,19,25,26,27,28,29,30",
|
||||||
|
"domain": "$AD_DOMAIN",
|
||||||
|
"ADServer": "$AD_SERVER"
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -224,6 +224,16 @@ func (dc *DomainConfig) HasRecordTypeName(rtype, name string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (dc *DomainConfig) Filter(f func(r *RecordConfig) bool) {
|
||||||
|
recs := []*RecordConfig{}
|
||||||
|
for _, r := range dc.Records {
|
||||||
|
if f(r) {
|
||||||
|
recs = append(recs, r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dc.Records = recs
|
||||||
|
}
|
||||||
|
|
||||||
func InterfaceToIP(i interface{}) (net.IP, error) {
|
func InterfaceToIP(i interface{}) (net.IP, error) {
|
||||||
switch v := i.(type) {
|
switch v := i.(type) {
|
||||||
case float64:
|
case float64:
|
||||||
|
@ -32,6 +32,14 @@ func (c *adProvider) GetNameservers(string) ([]*models.Nameserver, error) {
|
|||||||
// GetDomainCorrections gets existing records, diffs them against existing, and returns corrections.
|
// GetDomainCorrections gets existing records, diffs them against existing, and returns corrections.
|
||||||
func (c *adProvider) GetDomainCorrections(dc *models.DomainConfig) ([]*models.Correction, error) {
|
func (c *adProvider) GetDomainCorrections(dc *models.DomainConfig) ([]*models.Correction, error) {
|
||||||
|
|
||||||
|
dc.Filter(func(r *models.RecordConfig) bool {
|
||||||
|
if r.Type != "A" && r.Type != "CNAME" {
|
||||||
|
log.Printf("WARNING: Active Directory only manages A and CNAME records. Won't consider %s %s", r.Type, r.NameFQDN)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
|
||||||
// Read foundRecords:
|
// Read foundRecords:
|
||||||
foundRecords, err := c.getExistingRecords(dc.Name)
|
foundRecords, err := c.getExistingRecords(dc.Name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -80,17 +88,17 @@ func (c *adProvider) readZoneDump(domainname string) ([]byte, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// powerShellLogCommand logs to flagPsLog that a PowerShell command is going to be run.
|
// powerShellLogCommand logs to flagPsLog that a PowerShell command is going to be run.
|
||||||
func powerShellLogCommand(command string) error {
|
func logCommand(command string) error {
|
||||||
return logHelper(fmt.Sprintf("# %s\r\n%s\r\n", time.Now().UTC(), strings.TrimSpace(command)))
|
return logHelper(fmt.Sprintf("# %s\r\n%s\r\n", time.Now().UTC(), strings.TrimSpace(command)))
|
||||||
}
|
}
|
||||||
|
|
||||||
// powerShellLogOutput logs to flagPsLog that a PowerShell command is going to be run.
|
// powerShellLogOutput logs to flagPsLog that a PowerShell command is going to be run.
|
||||||
func powerShellLogOutput(s string) error {
|
func logOutput(s string) error {
|
||||||
return logHelper(fmt.Sprintf("OUTPUT: START\r\n%s\r\nOUTPUT: END\r\n", s))
|
return logHelper(fmt.Sprintf("OUTPUT: START\r\n%s\r\nOUTPUT: END\r\n", s))
|
||||||
}
|
}
|
||||||
|
|
||||||
// powerShellLogErr logs that a PowerShell command had an error.
|
// powerShellLogErr logs that a PowerShell command had an error.
|
||||||
func powerShellLogErr(e error) error {
|
func logErr(e error) error {
|
||||||
err := logHelper(fmt.Sprintf("ERROR: %v\r\r", e)) //Log error to powershell.log
|
err := logHelper(fmt.Sprintf("ERROR: %v\r\r", e)) //Log error to powershell.log
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err //Bubble up error created in logHelper
|
return err //Bubble up error created in logHelper
|
||||||
@ -101,14 +109,14 @@ func powerShellLogErr(e error) error {
|
|||||||
func logHelper(s string) error {
|
func logHelper(s string) error {
|
||||||
logfile, err := os.OpenFile(*flagPsLog, os.O_APPEND|os.O_RDWR|os.O_CREATE, 0660)
|
logfile, err := os.OpenFile(*flagPsLog, os.O_APPEND|os.O_RDWR|os.O_CREATE, 0660)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("ERROR: Can not create/append to %#v: %v\n", *flagPsLog, err)
|
return fmt.Errorf("error: Can not create/append to %#v: %v", *flagPsLog, err)
|
||||||
}
|
}
|
||||||
_, err = fmt.Fprintln(logfile, s)
|
_, err = fmt.Fprintln(logfile, s)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("ERROR: Append to %#v failed: %v\n", *flagPsLog, err)
|
return fmt.Errorf("error: Append to %#v failed: %v", *flagPsLog, err)
|
||||||
}
|
}
|
||||||
if logfile.Close() != nil {
|
if logfile.Close() != nil {
|
||||||
return fmt.Errorf("ERROR: Closing %#v failed: %v\n", *flagPsLog, err)
|
return fmt.Errorf("ERROR: Closing %#v failed: %v", *flagPsLog, err)
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -132,19 +140,19 @@ func (c *adProvider) getExistingRecords(domainname string) ([]*models.RecordConf
|
|||||||
// Get the JSON either from adzonedump or by running a PowerShell script.
|
// Get the JSON either from adzonedump or by running a PowerShell script.
|
||||||
data, err := c.getRecords(domainname)
|
data, err := c.getRecords(domainname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("getRecords failed on %#v: %v\n", domainname, err)
|
return nil, fmt.Errorf("getRecords failed on %#v: %v", domainname, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var recs []*RecordConfigJson
|
var recs []*RecordConfigJson
|
||||||
err = json.Unmarshal(data, &recs)
|
err = json.Unmarshal(data, &recs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("json.Unmarshal failed on %#v: %v\n", domainname, err)
|
return nil, fmt.Errorf("json.Unmarshal failed on %#v: %v", domainname, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
result := make([]*models.RecordConfig, 0, len(recs))
|
result := make([]*models.RecordConfig, 0, len(recs))
|
||||||
for i := range recs {
|
for i := range recs {
|
||||||
t, err := recs[i].unpackRecord(domainname)
|
t := recs[i].unpackRecord(domainname)
|
||||||
if err == nil {
|
if t != nil {
|
||||||
result = append(result, t)
|
result = append(result, t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -152,7 +160,7 @@ func (c *adProvider) getExistingRecords(domainname string) ([]*models.RecordConf
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *RecordConfigJson) unpackRecord(origin string) (*models.RecordConfig, error) {
|
func (r *RecordConfigJson) unpackRecord(origin string) *models.RecordConfig {
|
||||||
rc := models.RecordConfig{}
|
rc := models.RecordConfig{}
|
||||||
|
|
||||||
rc.Name = strings.ToLower(r.Name)
|
rc.Name = strings.ToLower(r.Name)
|
||||||
@ -165,37 +173,36 @@ func (r *RecordConfigJson) unpackRecord(origin string) (*models.RecordConfig, er
|
|||||||
rc.Target = r.Data
|
rc.Target = r.Data
|
||||||
case "CNAME":
|
case "CNAME":
|
||||||
rc.Target = strings.ToLower(r.Data)
|
rc.Target = strings.ToLower(r.Data)
|
||||||
case "AAAA", "MX", "NAPTR", "NS", "SOA", "SRV":
|
case "NS", "SOA":
|
||||||
return nil, fmt.Errorf("Unimplemented: %v", r.Type)
|
return nil
|
||||||
default:
|
default:
|
||||||
log.Fatalf("Unhandled models.RecordConfigJson type: %v (%v)\n", rc.Type, r)
|
log.Printf("Warning: Record of type %s found in AD zone. Will be ignored.", rc.Type)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
return &rc
|
||||||
return &rc, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// powerShellDump runs a PowerShell command to get a dump of all records in a DNS zone.
|
// powerShellDump runs a PowerShell command to get a dump of all records in a DNS zone.
|
||||||
func (c *adProvider) generatePowerShellZoneDump(domainname string) string {
|
func (c *adProvider) generatePowerShellZoneDump(domainname string) string {
|
||||||
cmd_txt := `@("REPLACE_WITH_ZONE") | %{
|
cmdTxt := `@("REPLACE_WITH_ZONE") | %{
|
||||||
Get-DnsServerResourceRecord -ComputerName REPLACE_WITH_COMPUTER_NAME -ZoneName $_ | select hostname,recordtype,@{n="timestamp";e={$_.timestamp.tostring()}},@{n="timetolive";e={$_.timetolive.totalseconds}},@{n="recorddata";e={($_.recorddata.ipv4address,$_.recorddata.ipv6address,$_.recorddata.HostNameAlias,"other_record" -ne $null)[0]-as [string]}} | ConvertTo-Json > REPLACE_WITH_FILENAMEPREFIX.REPLACE_WITH_ZONE.json
|
Get-DnsServerResourceRecord -ComputerName REPLACE_WITH_COMPUTER_NAME -ZoneName $_ | select hostname,recordtype,@{n="timestamp";e={$_.timestamp.tostring()}},@{n="timetolive";e={$_.timetolive.totalseconds}},@{n="recorddata";e={($_.recorddata.ipv4address,$_.recorddata.ipv6address,$_.recorddata.HostNameAlias,"other_record" -ne $null)[0]-as [string]}} | ConvertTo-Json > REPLACE_WITH_FILENAMEPREFIX.REPLACE_WITH_ZONE.json
|
||||||
}`
|
}`
|
||||||
cmd_txt = strings.Replace(cmd_txt, "REPLACE_WITH_ZONE", domainname, -1)
|
cmdTxt = strings.Replace(cmdTxt, "REPLACE_WITH_ZONE", domainname, -1)
|
||||||
cmd_txt = strings.Replace(cmd_txt, "REPLACE_WITH_COMPUTER_NAME", c.adServer, -1)
|
cmdTxt = strings.Replace(cmdTxt, "REPLACE_WITH_COMPUTER_NAME", c.adServer, -1)
|
||||||
cmd_txt = strings.Replace(cmd_txt, "REPLACE_WITH_FILENAMEPREFIX", zoneDumpFilenamePrefix, -1)
|
cmdTxt = strings.Replace(cmdTxt, "REPLACE_WITH_FILENAMEPREFIX", zoneDumpFilenamePrefix, -1)
|
||||||
|
|
||||||
return cmd_txt
|
return cmdTxt
|
||||||
}
|
}
|
||||||
|
|
||||||
// generatePowerShellCreate generates PowerShell commands to ADD a record.
|
// generatePowerShellCreate generates PowerShell commands to ADD a record.
|
||||||
func (c *adProvider) generatePowerShellCreate(domainname string, rec *models.RecordConfig) string {
|
func (c *adProvider) generatePowerShellCreate(domainname string, rec *models.RecordConfig) string {
|
||||||
|
|
||||||
content := rec.Target
|
content := rec.Target
|
||||||
|
|
||||||
text := "\r\n" // Skip a line.
|
text := "\r\n" // Skip a line.
|
||||||
text += fmt.Sprintf("Add-DnsServerResourceRecord%s", rec.Type)
|
text += fmt.Sprintf("Add-DnsServerResourceRecord%s", rec.Type)
|
||||||
text += fmt.Sprintf(` -ComputerName "%s"`, c.adServer)
|
text += fmt.Sprintf(` -ComputerName "%s"`, c.adServer)
|
||||||
text += fmt.Sprintf(` -ZoneName "%s"`, domainname)
|
text += fmt.Sprintf(` -ZoneName "%s"`, domainname)
|
||||||
text += fmt.Sprintf(` -Name "%s"`, rec.Name)
|
text += fmt.Sprintf(` -Name "%s"`, rec.Name)
|
||||||
|
text += fmt.Sprintf(` -TimeToLive $(New-TimeSpan -Seconds %d)`, rec.TTL)
|
||||||
switch rec.Type {
|
switch rec.Type {
|
||||||
case "CNAME":
|
case "CNAME":
|
||||||
text += fmt.Sprintf(` -HostNameAlias "%s"`, content)
|
text += fmt.Sprintf(` -HostNameAlias "%s"`, content)
|
||||||
@ -276,7 +283,7 @@ func (c *adProvider) createRec(domainname string, rec *models.RecordConfig) []*m
|
|||||||
{
|
{
|
||||||
Msg: fmt.Sprintf("CREATE record: %s %s ttl(%d) %s", rec.Name, rec.Type, rec.TTL, rec.Target),
|
Msg: fmt.Sprintf("CREATE record: %s %s ttl(%d) %s", rec.Name, rec.Type, rec.TTL, rec.Target),
|
||||||
F: func() error {
|
F: func() error {
|
||||||
return powerShellDoCommand(c.generatePowerShellCreate(domainname, rec))
|
return powerShellDoCommand(c.generatePowerShellCreate(domainname, rec), true)
|
||||||
}},
|
}},
|
||||||
}
|
}
|
||||||
return arr
|
return arr
|
||||||
@ -287,7 +294,7 @@ func (c *adProvider) modifyRec(domainname string, m diff.Correlation) *models.Co
|
|||||||
return &models.Correction{
|
return &models.Correction{
|
||||||
Msg: m.String(),
|
Msg: m.String(),
|
||||||
F: func() error {
|
F: func() error {
|
||||||
return powerShellDoCommand(c.generatePowerShellModify(domainname, rec.Name, rec.Type, old.Target, rec.Target, old.TTL, rec.TTL))
|
return powerShellDoCommand(c.generatePowerShellModify(domainname, rec.Name, rec.Type, old.Target, rec.Target, old.TTL, rec.TTL), true)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -296,7 +303,7 @@ func (c *adProvider) deleteRec(domainname string, rec *models.RecordConfig) *mod
|
|||||||
return &models.Correction{
|
return &models.Correction{
|
||||||
Msg: fmt.Sprintf("DELETE record: %s %s ttl(%d) %s", rec.Name, rec.Type, rec.TTL, rec.Target),
|
Msg: fmt.Sprintf("DELETE record: %s %s ttl(%d) %s", rec.Name, rec.Type, rec.TTL, rec.Target),
|
||||||
F: func() error {
|
F: func() error {
|
||||||
return powerShellDoCommand(c.generatePowerShellDelete(domainname, rec.Name, rec.Type, rec.Target))
|
return powerShellDoCommand(c.generatePowerShellDelete(domainname, rec.Name, rec.Type, rec.Target), true)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ func (c *adProvider) getRecords(domainname string) ([]byte, error) {
|
|||||||
return c.readZoneDump(domainname)
|
return c.readZoneDump(domainname)
|
||||||
}
|
}
|
||||||
|
|
||||||
func powerShellDoCommand(command string) error {
|
func powerShellDoCommand(command string, shouldLog bool) error {
|
||||||
if !*flagFakePowerShell {
|
if !*flagFakePowerShell {
|
||||||
panic("Can not happen: PowerShell on non-windows")
|
panic("Can not happen: PowerShell on non-windows")
|
||||||
}
|
}
|
||||||
|
@ -5,36 +5,44 @@ import (
|
|||||||
"os/exec"
|
"os/exec"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"sync"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var checkPS sync.Once
|
||||||
|
var psAvailible = false
|
||||||
|
|
||||||
func (c *adProvider) getRecords(domainname string) ([]byte, error) {
|
func (c *adProvider) getRecords(domainname string) ([]byte, error) {
|
||||||
|
|
||||||
if !*flagFakePowerShell {
|
// If we are using PowerShell, make sure it is enabled
|
||||||
// If we are using PowerShell, make sure it is enabled
|
// and then run the PS1 command to generate the adzonedump file.
|
||||||
// and then run the PS1 command to generate the adzonedump file.
|
|
||||||
|
|
||||||
if !isPowerShellReady() {
|
if !*flagFakePowerShell {
|
||||||
fmt.Printf("\n\n\n")
|
checkPS.Do(func() {
|
||||||
fmt.Printf("***********************************************\n")
|
psAvailible = isPowerShellReady()
|
||||||
fmt.Printf("PowerShell DnsServer module not installed.\n")
|
if !psAvailible {
|
||||||
fmt.Printf("See http://social.technet.microsoft.com/wiki/contents/articles/2202.remote-server-administration-tools-rsat-for-windows-client-and-windows-server-dsforum2wiki.aspx\n")
|
fmt.Printf("\n\n\n")
|
||||||
fmt.Printf("***********************************************\n")
|
fmt.Printf("***********************************************\n")
|
||||||
fmt.Printf("\n\n\n")
|
fmt.Printf("PowerShell DnsServer module not installed.\n")
|
||||||
return nil, fmt.Errorf("PowerShell module DnsServer not installed.")
|
fmt.Printf("See http://social.technet.microsoft.com/wiki/contents/articles/2202.remote-server-administration-tools-rsat-for-windows-client-and-windows-server-dsforum2wiki.aspx\n")
|
||||||
|
fmt.Printf("***********************************************\n")
|
||||||
|
fmt.Printf("\n\n\n")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if !psAvailible {
|
||||||
|
return nil, fmt.Errorf("powershell module DnsServer not installed")
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := powerShellExecCombined(c.generatePowerShellZoneDump(domainname))
|
_, err := powerShellExec(c.generatePowerShellZoneDump(domainname), true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []byte{}, err
|
return []byte{}, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the contents of zone.*.json file instead.
|
// Return the contents of zone.*.json file instead.
|
||||||
return c.readZoneDump(domainname)
|
return c.readZoneDump(domainname)
|
||||||
}
|
}
|
||||||
|
|
||||||
func isPowerShellReady() bool {
|
func isPowerShellReady() bool {
|
||||||
query, _ := powerShellExec(`(Get-Module -ListAvailable DnsServer) -ne $null`)
|
query, _ := powerShellExec(`(Get-Module -ListAvailable DnsServer) -ne $null`, true)
|
||||||
q, err := strconv.ParseBool(strings.TrimSpace(string(query)))
|
q, err := strconv.ParseBool(strings.TrimSpace(string(query)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
@ -42,52 +50,33 @@ func isPowerShellReady() bool {
|
|||||||
return q
|
return q
|
||||||
}
|
}
|
||||||
|
|
||||||
func powerShellDoCommand(command string) error {
|
func powerShellDoCommand(command string, shouldLog bool) error {
|
||||||
if *flagFakePowerShell {
|
if *flagFakePowerShell {
|
||||||
// If fake, just record the command.
|
// If fake, just record the command.
|
||||||
return powerShellRecord(command)
|
return powerShellRecord(command)
|
||||||
}
|
}
|
||||||
_, err := powerShellExec(command)
|
_, err := powerShellExec(command, shouldLog)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func powerShellExec(command string) ([]byte, error) {
|
func powerShellExec(command string, shouldLog bool) ([]byte, error) {
|
||||||
// log it.
|
// log it.
|
||||||
err := powerShellLogCommand(command)
|
err := logCommand(command)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return []byte{}, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Run it.
|
// Run it.
|
||||||
out, err := exec.Command("powershell", "-NoProfile", command).CombinedOutput()
|
out, err := exec.Command("powershell", "-NoProfile", command).CombinedOutput()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// If there was an error, log it.
|
// If there was an error, log it.
|
||||||
powerShellLogErr(err)
|
logErr(err)
|
||||||
}
|
}
|
||||||
// Return the result.
|
if shouldLog {
|
||||||
return out, err
|
err = logOutput(string(out))
|
||||||
}
|
if err != nil {
|
||||||
|
return []byte{}, err
|
||||||
// powerShellExecCombined runs a PS1 command and logs the output. This is useful when the output should be none or very small.
|
}
|
||||||
func powerShellExecCombined(command string) ([]byte, error) {
|
|
||||||
// log it.
|
|
||||||
err := powerShellLogCommand(command)
|
|
||||||
if err != nil {
|
|
||||||
return []byte{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Run it.
|
|
||||||
out, err := exec.Command("powershell", "-NoProfile", command).CombinedOutput()
|
|
||||||
if err != nil {
|
|
||||||
// If there was an error, log it.
|
|
||||||
powerShellLogErr(err)
|
|
||||||
return out, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// Log output.
|
|
||||||
err = powerShellLogOutput(string(out))
|
|
||||||
if err != nil {
|
|
||||||
return []byte{}, err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the result.
|
// Return the result.
|
||||||
|
Reference in New Issue
Block a user